summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go116
-rw-r--r--api/gobgp.proto35
-rw-r--r--gobgp/cmd/common.go51
-rw-r--r--gobgp/cmd/neighbor.go35
-rw-r--r--gobgp/lib/path.go12
-rw-r--r--packet/bgp.go149
-rw-r--r--packet/bgp_test.go2
-rw-r--r--server/fsm.go3
-rw-r--r--server/fsm_test.go2
-rw-r--r--server/peer.go12
10 files changed, 165 insertions, 252 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 182845ea..550863dc 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -15,9 +15,6 @@ It has these top-level messages:
PolicyArguments
MrtArguments
ModVrfArguments
- GracefulRestartTuple
- GracefulRestart
- Capability
Path
Destination
PeerConf
@@ -131,44 +128,6 @@ func (x Operation) String() string {
return proto.EnumName(Operation_name, int32(x))
}
-type BGP_CAPABILITY int32
-
-const (
- BGP_CAPABILITY_UNKNOWN_CAP BGP_CAPABILITY = 0
- BGP_CAPABILITY_MULTIPROTOCOL BGP_CAPABILITY = 1
- BGP_CAPABILITY_ROUTE_REFRESH BGP_CAPABILITY = 2
- BGP_CAPABILITY_CARRYING_LABEL_INFO BGP_CAPABILITY = 4
- BGP_CAPABILITY_GRACEFUL_RESTART BGP_CAPABILITY = 64
- BGP_CAPABILITY_FOUR_OCTET_AS_NUMBER BGP_CAPABILITY = 65
- BGP_CAPABILITY_ENHANCED_ROUTE_REFRESH BGP_CAPABILITY = 70
- BGP_CAPABILITY_ROUTE_REFRESH_CISCO BGP_CAPABILITY = 128
-)
-
-var BGP_CAPABILITY_name = map[int32]string{
- 0: "UNKNOWN_CAP",
- 1: "MULTIPROTOCOL",
- 2: "ROUTE_REFRESH",
- 4: "CARRYING_LABEL_INFO",
- 64: "GRACEFUL_RESTART",
- 65: "FOUR_OCTET_AS_NUMBER",
- 70: "ENHANCED_ROUTE_REFRESH",
- 128: "ROUTE_REFRESH_CISCO",
-}
-var BGP_CAPABILITY_value = map[string]int32{
- "UNKNOWN_CAP": 0,
- "MULTIPROTOCOL": 1,
- "ROUTE_REFRESH": 2,
- "CARRYING_LABEL_INFO": 4,
- "GRACEFUL_RESTART": 64,
- "FOUR_OCTET_AS_NUMBER": 65,
- "ENHANCED_ROUTE_REFRESH": 70,
- "ROUTE_REFRESH_CISCO": 128,
-}
-
-func (x BGP_CAPABILITY) String() string {
- return proto.EnumName(BGP_CAPABILITY_name, int32(x))
-}
-
type Error_ErrorCode int32
const (
@@ -281,50 +240,6 @@ func (m *ModVrfArguments) GetVrf() *Vrf {
return nil
}
-type GracefulRestartTuple struct {
- Rf uint32 `protobuf:"varint,1,opt,name=rf" json:"rf,omitempty"`
- Flags uint32 `protobuf:"varint,2,opt,name=flags" json:"flags,omitempty"`
-}
-
-func (m *GracefulRestartTuple) Reset() { *m = GracefulRestartTuple{} }
-func (m *GracefulRestartTuple) String() string { return proto.CompactTextString(m) }
-func (*GracefulRestartTuple) ProtoMessage() {}
-
-type GracefulRestart struct {
- Flags uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"`
- Time uint32 `protobuf:"varint,2,opt,name=time" json:"time,omitempty"`
- Tuples []*GracefulRestartTuple `protobuf:"bytes,3,rep,name=tuples" json:"tuples,omitempty"`
-}
-
-func (m *GracefulRestart) Reset() { *m = GracefulRestart{} }
-func (m *GracefulRestart) String() string { return proto.CompactTextString(m) }
-func (*GracefulRestart) ProtoMessage() {}
-
-func (m *GracefulRestart) GetTuples() []*GracefulRestartTuple {
- if m != nil {
- return m.Tuples
- }
- return nil
-}
-
-type Capability struct {
- Code BGP_CAPABILITY `protobuf:"varint,1,opt,name=code,enum=api.BGP_CAPABILITY" json:"code,omitempty"`
- MultiProtocol uint32 `protobuf:"varint,2,opt,name=multi_protocol" json:"multi_protocol,omitempty"`
- GracefulRestart *GracefulRestart `protobuf:"bytes,3,opt,name=graceful_restart" json:"graceful_restart,omitempty"`
- Asn uint32 `protobuf:"varint,4,opt,name=asn" json:"asn,omitempty"`
-}
-
-func (m *Capability) Reset() { *m = Capability{} }
-func (m *Capability) String() string { return proto.CompactTextString(m) }
-func (*Capability) ProtoMessage() {}
-
-func (m *Capability) GetGracefulRestart() *GracefulRestart {
- if m != nil {
- return m.GracefulRestart
- }
- return nil
-}
-
type Path struct {
Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"`
Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"`
@@ -357,35 +272,19 @@ func (m *Destination) GetPaths() []*Path {
}
type PeerConf struct {
- RemoteIp string `protobuf:"bytes,1,opt,name=remote_ip" json:"remote_ip,omitempty"`
- Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
- RemoteAs uint32 `protobuf:"varint,3,opt,name=remote_as" json:"remote_as,omitempty"`
- CapRefresh bool `protobuf:"varint,4,opt,name=cap_refresh" json:"cap_refresh,omitempty"`
- CapEnhancedRefresh bool `protobuf:"varint,5,opt,name=cap_enhanced_refresh" json:"cap_enhanced_refresh,omitempty"`
- RemoteCap []*Capability `protobuf:"bytes,6,rep,name=remote_cap" json:"remote_cap,omitempty"`
- LocalCap []*Capability `protobuf:"bytes,7,rep,name=local_cap" json:"local_cap,omitempty"`
- Holdtime uint32 `protobuf:"varint,8,opt,name=holdtime" json:"holdtime,omitempty"`
- KeepaliveInterval uint32 `protobuf:"varint,9,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"`
+ RemoteIp string `protobuf:"bytes,1,opt,name=remote_ip" json:"remote_ip,omitempty"`
+ Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
+ RemoteAs uint32 `protobuf:"varint,3,opt,name=remote_as" json:"remote_as,omitempty"`
+ RemoteCap [][]byte `protobuf:"bytes,6,rep,name=remote_cap,proto3" json:"remote_cap,omitempty"`
+ LocalCap [][]byte `protobuf:"bytes,7,rep,name=local_cap,proto3" json:"local_cap,omitempty"`
+ Holdtime uint32 `protobuf:"varint,8,opt,name=holdtime" json:"holdtime,omitempty"`
+ KeepaliveInterval uint32 `protobuf:"varint,9,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"`
}
func (m *PeerConf) Reset() { *m = PeerConf{} }
func (m *PeerConf) String() string { return proto.CompactTextString(m) }
func (*PeerConf) ProtoMessage() {}
-func (m *PeerConf) GetRemoteCap() []*Capability {
- if m != nil {
- return m.RemoteCap
- }
- return nil
-}
-
-func (m *PeerConf) GetLocalCap() []*Capability {
- if m != nil {
- return m.LocalCap
- }
- return nil
-}
-
type PeerInfo struct {
BgpState string `protobuf:"bytes,1,opt,name=bgp_state" json:"bgp_state,omitempty"`
AdminState string `protobuf:"bytes,2,opt,name=admin_state" json:"admin_state,omitempty"`
@@ -788,7 +687,6 @@ func (*Vrf) ProtoMessage() {}
func init() {
proto.RegisterEnum("api.Resource", Resource_name, Resource_value)
proto.RegisterEnum("api.Operation", Operation_name, Operation_value)
- proto.RegisterEnum("api.BGP_CAPABILITY", BGP_CAPABILITY_name, BGP_CAPABILITY_value)
proto.RegisterEnum("api.Error_ErrorCode", Error_ErrorCode_name, Error_ErrorCode_value)
}
diff --git a/api/gobgp.proto b/api/gobgp.proto
index f08d5b26..ba39250c 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -109,35 +109,6 @@ enum Operation {
DEL_ALL = 2;
}
-enum BGP_CAPABILITY {
- UNKNOWN_CAP = 0;
- MULTIPROTOCOL = 1;
- ROUTE_REFRESH = 2;
- CARRYING_LABEL_INFO = 4;
- GRACEFUL_RESTART = 64;
- FOUR_OCTET_AS_NUMBER = 65;
- ENHANCED_ROUTE_REFRESH = 70;
- ROUTE_REFRESH_CISCO = 128;
-}
-
-message GracefulRestartTuple {
- uint32 rf = 1;
- uint32 flags = 2;
-}
-
-message GracefulRestart {
- uint32 flags = 1;
- uint32 time = 2;
- repeated GracefulRestartTuple tuples = 3;
-}
-
-message Capability {
- BGP_CAPABILITY code = 1;
- uint32 multi_protocol = 2;
- GracefulRestart graceful_restart = 3;
- uint32 asn = 4;
-}
-
message Path {
bytes nlri = 1;
repeated bytes pattrs = 2;
@@ -158,10 +129,8 @@ message PeerConf {
string remote_ip = 1;
string id = 2;
uint32 remote_as = 3;
- bool cap_refresh = 4;
- bool cap_enhanced_refresh = 5;
- repeated Capability remote_cap = 6;
- repeated Capability local_cap = 7;
+ repeated bytes remote_cap = 6;
+ repeated bytes local_cap = 7;
uint32 holdtime = 8;
uint32 keepalive_interval = 9;
}
diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go
index 50b22fa9..4d828366 100644
--- a/gobgp/cmd/common.go
+++ b/gobgp/cmd/common.go
@@ -221,7 +221,48 @@ func (p paths) Less(i, j int) bool {
return strings.Less(0, 1)
}
-type peers []*api.Peer
+type PeerConf struct {
+ RemoteIp net.IP `json:"remote_ip,omitempty"`
+ Id net.IP `json:"id,omitempty"`
+ RemoteAs uint32 `json:"remote_as,omitempty"`
+ RemoteCap []bgp.ParameterCapabilityInterface `json:"remote_cap,omitempty"`
+ LocalCap []bgp.ParameterCapabilityInterface `json:"local_cap,omitempty"`
+ Holdtime uint32 `json:"holdtime,omitempty"`
+ KeepaliveInterval uint32 `json:"keepalive_interval,omitempty"`
+}
+
+type Peer struct {
+ Conf PeerConf `json:"conf,omitempty"`
+ Info *api.PeerInfo `json:"info,omitempty"`
+}
+
+func ApiStruct2Peer(p *api.Peer) *Peer {
+ localCaps := capabilities{}
+ remoteCaps := capabilities{}
+ for _, buf := range p.Conf.LocalCap {
+ c, _ := bgp.DecodeCapability(buf)
+ localCaps = append(localCaps, c)
+ }
+ for _, buf := range p.Conf.RemoteCap {
+ c, _ := bgp.DecodeCapability(buf)
+ remoteCaps = append(remoteCaps, c)
+ }
+ conf := PeerConf{
+ RemoteIp: net.ParseIP(p.Conf.RemoteIp),
+ Id: net.ParseIP(p.Conf.Id),
+ RemoteAs: p.Conf.RemoteAs,
+ RemoteCap: remoteCaps,
+ LocalCap: localCaps,
+ Holdtime: p.Conf.Holdtime,
+ KeepaliveInterval: p.Conf.KeepaliveInterval,
+ }
+ return &Peer{
+ Conf: conf,
+ Info: p.Info,
+ }
+}
+
+type peers []*Peer
func (p peers) Len() int {
return len(p)
@@ -232,8 +273,8 @@ func (p peers) Swap(i, j int) {
}
func (p peers) Less(i, j int) bool {
- p1 := net.ParseIP(p[i].Conf.RemoteIp)
- p2 := net.ParseIP(p[j].Conf.RemoteIp)
+ p1 := p[i].Conf.RemoteIp
+ p2 := p[j].Conf.RemoteIp
p1Isv4 := p1.To4() != nil
p2Isv4 := p2.To4() != nil
if p1Isv4 != p2Isv4 {
@@ -251,7 +292,7 @@ func (p peers) Less(i, j int) bool {
return strings.Less(0, 1)
}
-type capabilities []*api.Capability
+type capabilities []bgp.ParameterCapabilityInterface
func (c capabilities) Len() int {
return len(c)
@@ -262,7 +303,7 @@ func (c capabilities) Swap(i, j int) {
}
func (c capabilities) Less(i, j int) bool {
- return c[i].Code < c[j].Code
+ return c[i].Code() < c[j].Code()
}
type prefixes []*api.PrefixSet
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index d7037145..520a2c27 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -59,7 +59,7 @@ func getNeighbors() (peers, error) {
}
}
}
- m = append(m, p)
+ m = append(m, ApiStruct2Peer(p))
}
return m, nil
}
@@ -144,10 +144,11 @@ func showNeighbor(args []string) error {
id := &api.Arguments{
Name: args[0],
}
- p, e := client.GetNeighbor(context.Background(), id)
+ peer, e := client.GetNeighbor(context.Background(), id)
if e != nil {
return e
}
+ p := ApiStruct2Peer(peer)
if globalOpts.Json {
j, _ := json.Marshal(p)
@@ -164,11 +165,13 @@ func showNeighbor(args []string) error {
fmt.Printf(" Neighbor capabilities:\n")
caps := capabilities{}
- lookup := func(val *api.Capability, l capabilities) *api.Capability {
+ lookup := func(val bgp.ParameterCapabilityInterface, l capabilities) bgp.ParameterCapabilityInterface {
for _, v := range l {
- if v.Code == val.Code {
- if v.Code == api.BGP_CAPABILITY_MULTIPROTOCOL {
- if v.MultiProtocol == val.MultiProtocol {
+ if v.Code() == val.Code() {
+ if v.Code() == bgp.BGP_CAP_MULTIPROTOCOL {
+ lhs := v.(*bgp.CapMultiProtocol).CapValue
+ rhs := val.(*bgp.CapMultiProtocol).CapValue
+ if lhs == rhs {
return v
}
continue
@@ -178,10 +181,12 @@ func showNeighbor(args []string) error {
}
return nil
}
- caps = append(caps, p.Conf.LocalCap...)
- for _, v := range p.Conf.RemoteCap {
- if lookup(v, caps) == nil {
- caps = append(caps, v)
+ for _, c := range p.Conf.LocalCap {
+ caps = append(caps, c)
+ }
+ for _, c := range p.Conf.RemoteCap {
+ if lookup(c, caps) == nil {
+ caps = append(caps, c)
}
}
@@ -201,15 +206,15 @@ func showNeighbor(args []string) error {
support += "received"
}
- if c.Code != api.BGP_CAPABILITY_MULTIPROTOCOL {
- fmt.Printf(" %s:\t%s\n", c.Code, support)
+ if c.Code() != bgp.BGP_CAP_MULTIPROTOCOL {
+ fmt.Printf(" %s:\t%s\n", c.Code(), support)
} else {
if firstMp {
- fmt.Printf(" %s:\n", c.Code)
+ fmt.Printf(" %s:\n", c.Code())
firstMp = false
}
- fmt.Printf(" %s:\t%s\n", bgp.RouteFamily(c.MultiProtocol), support)
-
+ m := c.(*bgp.CapMultiProtocol).CapValue
+ fmt.Printf(" %s:\t%s\n", m, support)
}
}
fmt.Print(" Message statistics:\n")
diff --git a/gobgp/lib/path.go b/gobgp/lib/path.go
index d749eb6a..1788c98c 100644
--- a/gobgp/lib/path.go
+++ b/gobgp/lib/path.go
@@ -114,6 +114,18 @@ func decode_path(p *C.path) *C.char {
return C.CString(string(j))
}
+//export decode_capabilities
+func decode_capabilities(p *C.buf) *C.char {
+ buf := []byte(C.GoStringN(p.value, p.len))
+ c, err := bgp.DecodeCapability(buf)
+ if err != nil {
+ return nil
+ }
+ j, _ := json.Marshal(c)
+ return C.CString(string(j))
+
+}
+
func main() {
// We need the main function to make possible
// CGO compiler to compile the package as C shared library
diff --git a/packet/bgp.go b/packet/bgp.go
index 1b07ec33..f2f673e8 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -20,7 +20,6 @@ import (
"encoding/binary"
"encoding/json"
"fmt"
- "github.com/osrg/gobgp/api"
"math"
"net"
"reflect"
@@ -215,13 +214,12 @@ type ParameterCapabilityInterface interface {
Serialize() ([]byte, error)
Len() int
Code() BGPCapabilityCode
- ToApiStruct() *api.Capability
}
type DefaultParameterCapability struct {
- CapCode BGPCapabilityCode
- CapLen uint8
- CapValue []byte
+ CapCode BGPCapabilityCode `json:"code"`
+ CapLen uint8 `json:"-"`
+ CapValue []byte `json:"value,omitempty"`
}
func (c *DefaultParameterCapability) Code() BGPCapabilityCode {
@@ -253,20 +251,9 @@ func (c *DefaultParameterCapability) Len() int {
return int(c.CapLen + 2)
}
-func (c *DefaultParameterCapability) ToApiStruct() *api.Capability {
- return &api.Capability{
- Code: api.BGP_CAPABILITY(c.Code()),
- }
-}
-
-type CapMultiProtocolValue struct {
- AFI uint16
- SAFI uint8
-}
-
type CapMultiProtocol struct {
DefaultParameterCapability
- CapValue CapMultiProtocolValue
+ CapValue RouteFamily
}
func (c *CapMultiProtocol) DecodeFromBytes(data []byte) error {
@@ -275,35 +262,35 @@ func (c *CapMultiProtocol) DecodeFromBytes(data []byte) error {
if len(data) < 4 {
return fmt.Errorf("Not all CapabilityMultiProtocol bytes available")
}
- c.CapValue.AFI = binary.BigEndian.Uint16(data[0:2])
- c.CapValue.SAFI = data[3]
+ c.CapValue = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[0:2]), data[3])
return nil
}
func (c *CapMultiProtocol) Serialize() ([]byte, error) {
buf := make([]byte, 4)
- binary.BigEndian.PutUint16(buf[0:], c.CapValue.AFI)
- buf[3] = c.CapValue.SAFI
+ afi, safi := RouteFamilyToAfiSafi(c.CapValue)
+ binary.BigEndian.PutUint16(buf[0:], afi)
+ buf[3] = safi
c.DefaultParameterCapability.CapValue = buf
return c.DefaultParameterCapability.Serialize()
}
-func (c *CapMultiProtocol) ToApiStruct() *api.Capability {
- return &api.Capability{
- Code: api.BGP_CAPABILITY(c.Code()),
- MultiProtocol: uint32(AfiSafiToRouteFamily(c.CapValue.AFI, c.CapValue.SAFI)),
- }
+func (c *CapMultiProtocol) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Code BGPCapabilityCode `json:"code"`
+ Value RouteFamily `json:"value"`
+ }{
+ Code: c.Code(),
+ Value: c.CapValue,
+ })
}
-func NewCapMultiProtocol(afi uint16, safi uint8) *CapMultiProtocol {
+func NewCapMultiProtocol(rf RouteFamily) *CapMultiProtocol {
return &CapMultiProtocol{
DefaultParameterCapability{
CapCode: BGP_CAP_MULTIPROTOCOL,
},
- CapMultiProtocolValue{
- AFI: afi,
- SAFI: safi,
- },
+ rf,
}
}
@@ -329,10 +316,20 @@ type CapGracefulRestartTuples struct {
Flags uint8
}
+func (c CapGracefulRestartTuples) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ RouteFamily RouteFamily `json:"route_family"`
+ Flags uint8 `json:"flags"`
+ }{
+ RouteFamily: AfiSafiToRouteFamily(c.AFI, c.SAFI),
+ Flags: c.Flags,
+ })
+}
+
type CapGracefulRestartValue struct {
- Flags uint8
- Time uint16
- Tuples []CapGracefulRestartTuples
+ Flags uint8 `json:"flags"`
+ Time uint16 `json:"time"`
+ Tuples []CapGracefulRestartTuples `json"tuples"`
}
type CapGracefulRestart struct {
@@ -370,27 +367,6 @@ func (c *CapGracefulRestart) Serialize() ([]byte, error) {
return c.DefaultParameterCapability.Serialize()
}
-func (c *CapGracefulRestart) ToApiStruct() *api.Capability {
- value := &api.GracefulRestart{
- Flags: uint32(c.CapValue.Flags),
- Time: uint32(c.CapValue.Time),
- }
- tuples := []*api.GracefulRestartTuple{}
- for _, t := range c.CapValue.Tuples {
- tuple := &api.GracefulRestartTuple{
- Rf: uint32(AfiSafiToRouteFamily(t.AFI, t.SAFI)),
- Flags: uint32(t.Flags),
- }
- tuples = append(tuples, tuple)
-
- }
- value.Tuples = tuples
- return &api.Capability{
- Code: api.BGP_CAPABILITY(c.Code()),
- GracefulRestart: value,
- }
-}
-
func NewCapGracefulRestart(flags uint8, time uint16, tuples []CapGracefulRestartTuples) *CapGracefulRestart {
return &CapGracefulRestart{
DefaultParameterCapability{
@@ -426,11 +402,14 @@ func (c *CapFourOctetASNumber) Serialize() ([]byte, error) {
return c.DefaultParameterCapability.Serialize()
}
-func (c *CapFourOctetASNumber) ToApiStruct() *api.Capability {
- return &api.Capability{
- Code: api.BGP_CAPABILITY(c.Code()),
- Asn: c.CapValue,
- }
+func (c *CapFourOctetASNumber) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Code BGPCapabilityCode `json"code"`
+ Value uint32 `json"value"`
+ }{
+ Code: c.Code(),
+ Value: c.CapValue,
+ })
}
func NewCapFourOctetASNumber(asnum uint32) *CapFourOctetASNumber {
@@ -470,6 +449,33 @@ type CapUnknown struct {
DefaultParameterCapability
}
+func DecodeCapability(data []byte) (ParameterCapabilityInterface, error) {
+ if len(data) < 2 {
+ return nil, fmt.Errorf("Not all ParameterCapability bytes available")
+ }
+ var c ParameterCapabilityInterface
+ switch BGPCapabilityCode(data[0]) {
+ case BGP_CAP_MULTIPROTOCOL:
+ c = &CapMultiProtocol{}
+ case BGP_CAP_ROUTE_REFRESH:
+ c = &CapRouteRefresh{}
+ case BGP_CAP_CARRYING_LABEL_INFO:
+ c = &CapCarryingLabelInfo{}
+ case BGP_CAP_GRACEFUL_RESTART:
+ c = &CapGracefulRestart{}
+ case BGP_CAP_FOUR_OCTET_AS_NUMBER:
+ c = &CapFourOctetASNumber{}
+ case BGP_CAP_ENHANCED_ROUTE_REFRESH:
+ c = &CapEnhancedRouteRefresh{}
+ case BGP_CAP_ROUTE_REFRESH_CISCO:
+ c = &CapRouteRefreshCisco{}
+ default:
+ c = &CapUnknown{}
+ }
+ err := c.DecodeFromBytes(data)
+ return c, err
+}
+
type OptionParameterInterface interface {
Serialize() ([]byte, error)
}
@@ -485,28 +491,9 @@ func (o *OptionParameterCapability) DecodeFromBytes(data []byte) error {
return fmt.Errorf("Not all OptionParameterCapability bytes available")
}
for len(data) >= 2 {
- var c ParameterCapabilityInterface
- switch BGPCapabilityCode(data[0]) {
- case BGP_CAP_MULTIPROTOCOL:
- c = &CapMultiProtocol{}
- case BGP_CAP_ROUTE_REFRESH:
- c = &CapRouteRefresh{}
- case BGP_CAP_CARRYING_LABEL_INFO:
- c = &CapCarryingLabelInfo{}
- case BGP_CAP_GRACEFUL_RESTART:
- c = &CapGracefulRestart{}
- case BGP_CAP_FOUR_OCTET_AS_NUMBER:
- c = &CapFourOctetASNumber{}
- case BGP_CAP_ENHANCED_ROUTE_REFRESH:
- c = &CapEnhancedRouteRefresh{}
- case BGP_CAP_ROUTE_REFRESH_CISCO:
- c = &CapRouteRefreshCisco{}
- default:
- c = &CapUnknown{}
- }
- err := c.DecodeFromBytes(data)
+ c, err := DecodeCapability(data)
if err != nil {
- return nil
+ return err
}
o.Capability = append(o.Capability, c)
data = data[c.Len():]
diff --git a/packet/bgp_test.go b/packet/bgp_test.go
index 20664ba0..5b0e462c 100644
--- a/packet/bgp_test.go
+++ b/packet/bgp_test.go
@@ -25,7 +25,7 @@ func open() *BGPMessage {
p1 := NewOptionParameterCapability(
[]ParameterCapabilityInterface{NewCapRouteRefresh()})
p2 := NewOptionParameterCapability(
- []ParameterCapabilityInterface{NewCapMultiProtocol(3, 4)})
+ []ParameterCapabilityInterface{NewCapMultiProtocol(RF_IPv4_UC)})
g := CapGracefulRestartTuples{4, 2, 3}
p3 := NewOptionParameterCapability(
[]ParameterCapabilityInterface{NewCapGracefulRestart(2, 100,
diff --git a/server/fsm.go b/server/fsm.go
index c255c021..c9950a5d 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -391,8 +391,7 @@ func capabilitiesFromConfig(gConf *config.Global, pConf *config.Neighbor) []bgp.
caps = append(caps, bgp.NewCapRouteRefresh())
for _, rf := range pConf.AfiSafis.AfiSafiList {
k, _ := bgp.GetRouteFamily(rf.AfiSafiName)
- afi, safi := bgp.RouteFamilyToAfiSafi(k)
- caps = append(caps, bgp.NewCapMultiProtocol(afi, safi))
+ caps = append(caps, bgp.NewCapMultiProtocol(k))
}
caps = append(caps, bgp.NewCapFourOctetASNumber(gConf.GlobalConfig.As))
return caps
diff --git a/server/fsm_test.go b/server/fsm_test.go
index db9be4b3..72dfe05f 100644
--- a/server/fsm_test.go
+++ b/server/fsm_test.go
@@ -313,7 +313,7 @@ func open() *bgp.BGPMessage {
p1 := bgp.NewOptionParameterCapability(
[]bgp.ParameterCapabilityInterface{bgp.NewCapRouteRefresh()})
p2 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapMultiProtocol(3, 4)})
+ []bgp.ParameterCapabilityInterface{bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC)})
g := bgp.CapGracefulRestartTuples{4, 2, 3}
p3 := bgp.NewOptionParameterCapability(
[]bgp.ParameterCapabilityInterface{bgp.NewCapGracefulRestart(2, 100,
diff --git a/server/peer.go b/server/peer.go
index 67e2c437..45cb1c79 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -135,7 +135,7 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) ([]*table.Path, bool, []*b
if c.Code() == bgp.BGP_CAP_MULTIPROTOCOL {
m := c.(*bgp.CapMultiProtocol)
- r[bgp.AfiSafiToRouteFamily(m.CapValue.AFI, m.CapValue.SAFI)] = true
+ r[m.CapValue] = true
}
}
}
@@ -246,17 +246,19 @@ func (peer *Peer) ToApiStruct() *api.Peer {
f := peer.fsm
c := f.pConf
- remoteCap := make([]*api.Capability, 0, len(peer.capMap))
+ remoteCap := make([][]byte, 0, len(peer.capMap))
for _, c := range peer.capMap {
for _, m := range c {
- remoteCap = append(remoteCap, m.ToApiStruct())
+ buf, _ := m.Serialize()
+ remoteCap = append(remoteCap, buf)
}
}
caps := capabilitiesFromConfig(&peer.gConf, &peer.conf)
- localCap := make([]*api.Capability, 0, len(caps))
+ localCap := make([][]byte, 0, len(caps))
for _, c := range caps {
- localCap = append(localCap, c.ToApiStruct())
+ buf, _ := c.Serialize()
+ localCap = append(localCap, buf)
}
conf := &api.PeerConf{