diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-06-23 15:44:16 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-06-23 15:44:16 +0900 |
commit | 1747a3311c7a29a3d58a223e70e37e854460b852 (patch) | |
tree | ca1fb1a668b7892a389fd53d1d450bd1f9f39937 | |
parent | dee06c638b0f3a1a4196d85a165aabb0383f3aab (diff) |
packet: fix addpath capability parser/serializer
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | packet/bgp/bgp.go | 63 | ||||
-rw-r--r-- | packet/bgp/helper.go | 2 |
2 files changed, 46 insertions, 19 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 034a2bcb..a32ce069 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -590,52 +590,79 @@ func (m BGPAddPathMode) String() string { } } -type CapAddPath struct { - DefaultParameterCapability +type CapAddPathTuple struct { RouteFamily RouteFamily Mode BGPAddPathMode } +func (t *CapAddPathTuple) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + RouteFamily RouteFamily `json:"family"` + Mode uint8 `json:"mode"` + }{ + RouteFamily: t.RouteFamily, + Mode: uint8(t.Mode), + }) +} + +func NewCapAddPathTuple(family RouteFamily, mode BGPAddPathMode) *CapAddPathTuple { + return &CapAddPathTuple{ + RouteFamily: family, + Mode: mode, + } +} + +type CapAddPath struct { + DefaultParameterCapability + Tuples []*CapAddPathTuple +} + func (c *CapAddPath) DecodeFromBytes(data []byte) error { c.DefaultParameterCapability.DecodeFromBytes(data) data = data[2:] if len(data) < 4 { return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityAddPath bytes available") } - c.RouteFamily = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2]) - c.Mode = BGPAddPathMode(data[3]) + c.Tuples = []*CapAddPathTuple{} + for len(data) >= 4 { + t := &CapAddPathTuple{ + RouteFamily: AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2]), + Mode: BGPAddPathMode(data[3]), + } + c.Tuples = append(c.Tuples, t) + data = data[4:] + } return nil } func (c *CapAddPath) Serialize() ([]byte, error) { - buf := make([]byte, 4) - afi, safi := RouteFamilyToAfiSafi(c.RouteFamily) - binary.BigEndian.PutUint16(buf, afi) - buf[2] = safi - buf[3] = byte(c.Mode) + buf := make([]byte, len(c.Tuples)*4) + for i, t := range c.Tuples { + afi, safi := RouteFamilyToAfiSafi(t.RouteFamily) + binary.BigEndian.PutUint16(buf[i*4:i*4+2], afi) + buf[i*4+2] = safi + buf[i*4+3] = byte(t.Mode) + } c.DefaultParameterCapability.CapValue = buf return c.DefaultParameterCapability.Serialize() } func (c *CapAddPath) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Code BGPCapabilityCode `json:"code"` - Value RouteFamily `json:"value"` - Mode BGPAddPathMode `json:"mode"` + Code BGPCapabilityCode `json:"code"` + Tuples []*CapAddPathTuple `json:"tuples"` }{ - Code: c.Code(), - Value: c.RouteFamily, - Mode: c.Mode, + Code: c.Code(), + Tuples: c.Tuples, }) } -func NewCapAddPath(rf RouteFamily, mode BGPAddPathMode) *CapAddPath { +func NewCapAddPath(tuples []*CapAddPathTuple) *CapAddPath { return &CapAddPath{ DefaultParameterCapability: DefaultParameterCapability{ CapCode: BGP_CAP_ADD_PATH, }, - RouteFamily: rf, - Mode: mode, + Tuples: tuples, } } diff --git a/packet/bgp/helper.go b/packet/bgp/helper.go index 1a06db1e..d97095f9 100644 --- a/packet/bgp/helper.go +++ b/packet/bgp/helper.go @@ -31,7 +31,7 @@ func NewTestBGPOpenMessage() *BGPMessage { p4 := NewOptionParameterCapability( []ParameterCapabilityInterface{NewCapFourOctetASNumber(100000)}) p5 := NewOptionParameterCapability( - []ParameterCapabilityInterface{NewCapAddPath(RF_IPv4_UC, BGP_ADD_PATH_BOTH)}) + []ParameterCapabilityInterface{NewCapAddPath([]*CapAddPathTuple{NewCapAddPathTuple(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})}) return NewBGPOpenMessage(11033, 303, "100.4.10.3", []OptionParameterInterface{p1, p2, p3, p4, p5}) } |