summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packet/bgp.go26
-rw-r--r--packet/bgp_test.go106
2 files changed, 92 insertions, 40 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index fa495edd..096444dc 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -1046,11 +1046,19 @@ func NewLabelledIPv6AddrPrefix(length uint8, prefix string, label Label) *Labell
}
type RouteTargetMembershipNLRI struct {
+ Length uint8
AS uint32
RouteTarget ExtendedCommunityInterface
}
func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte) error {
+ n.Length = data[0]
+ data = data[1:]
+ if len(data) == 0 {
+ return nil
+ } else if len(data) != 12 {
+ return fmt.Errorf("Not all RouteTargetMembershipNLRI bytes available")
+ }
n.AS = binary.BigEndian.Uint32(data[0:4])
rt, err := parseExtended(data[4:])
n.RouteTarget = rt
@@ -1061,13 +1069,18 @@ func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte) error {
}
func (n *RouteTargetMembershipNLRI) Serialize() ([]byte, error) {
- buf := make([]byte, 4)
- binary.BigEndian.PutUint32(buf, n.AS)
+ if n.RouteTarget == nil {
+ return []byte{0}, nil
+ }
+ buf := make([]byte, 5)
+ buf[0] = 12 * 8
+ binary.BigEndian.PutUint32(buf[1:], n.AS)
ebuf, err := n.RouteTarget.Serialize()
if err != nil {
return nil, err
}
- return append(buf, ebuf...), nil
+ buf = append(buf, ebuf...)
+ return buf, nil
}
func (n *RouteTargetMembershipNLRI) AFI() uint16 {
@@ -1078,7 +1091,12 @@ func (n *RouteTargetMembershipNLRI) SAFI() uint8 {
return SAFI_ROUTE_TARGET_CONSTRTAINS
}
-func (n *RouteTargetMembershipNLRI) Len() int { return 12 }
+func (n *RouteTargetMembershipNLRI) Len() int {
+ if n.AS == 0 && n.RouteTarget == nil {
+ return 1
+ }
+ return 13
+}
func (n *RouteTargetMembershipNLRI) String() string {
return fmt.Sprintf("%d:%s/%d", n.AS, n.RouteTarget.String(), n.Len()*8)
diff --git a/packet/bgp_test.go b/packet/bgp_test.go
index 839d8f23..3b5d7b4c 100644
--- a/packet/bgp_test.go
+++ b/packet/bgp_test.go
@@ -170,54 +170,88 @@ func Test_IPAddrPrefixString(t *testing.T) {
}
func Test_RouteTargetMembershipNLRIString(t *testing.T) {
- r := &RouteTargetMembershipNLRI{}
-
assert := assert.New(t)
// TwoOctetAsSpecificExtended
- buf := make([]byte, 12)
- binary.BigEndian.PutUint32(buf[:4], 65546)
- buf[4] = byte(EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC) // typehigh
- binary.BigEndian.PutUint16(buf[6:8], 65000)
- binary.BigEndian.PutUint32(buf[8:], 65546)
- r.DecodeFromBytes(buf)
- assert.Equal("65546:65000:65546/96", r.String())
+ buf := make([]byte, 13)
+ buf[0] = 12
+ binary.BigEndian.PutUint32(buf[1:5], 65546)
+ buf[5] = byte(EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC) // typehigh
+ binary.BigEndian.PutUint16(buf[7:9], 65000)
+ binary.BigEndian.PutUint32(buf[9:], 65546)
+ r := &RouteTargetMembershipNLRI{}
+ err := r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:65000:65546", r.String())
+ buf, err = r.Serialize()
+ assert.Equal(nil, err)
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:65000:65546", r.String())
// IPv4AddressSpecificExtended
- buf = make([]byte, 12)
- binary.BigEndian.PutUint32(buf[:4], 65546)
- buf[4] = byte(EC_TYPE_TRANSITIVE_IP4_SPECIFIC) // typehigh
+ buf = make([]byte, 13)
+ binary.BigEndian.PutUint32(buf[1:5], 65546)
+ buf[5] = byte(EC_TYPE_TRANSITIVE_IP4_SPECIFIC) // typehigh
ip := net.ParseIP("10.0.0.1").To4()
- copy(buf[6:10], []byte(ip))
- binary.BigEndian.PutUint16(buf[10:], 65000)
- r.DecodeFromBytes(buf)
- assert.Equal("65546:10.0.0.1:65000/96", r.String())
+ copy(buf[7:11], []byte(ip))
+ binary.BigEndian.PutUint16(buf[11:], 65000)
+ r = &RouteTargetMembershipNLRI{}
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:10.0.0.1:65000", r.String())
+ buf, err = r.Serialize()
+ assert.Equal(nil, err)
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:10.0.0.1:65000", r.String())
// FourOctetAsSpecificExtended
- buf = make([]byte, 12)
- binary.BigEndian.PutUint32(buf[:4], 65546)
- buf[4] = byte(EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) // typehigh
- buf[5] = byte(EC_SUBTYPE_ROUTE_TARGET) // subtype
- binary.BigEndian.PutUint32(buf[6:], 65546)
- binary.BigEndian.PutUint16(buf[10:], 65000)
- r.DecodeFromBytes(buf)
- assert.Equal("65546:1.10:65000/96", r.String())
+ buf = make([]byte, 13)
+ binary.BigEndian.PutUint32(buf[1:5], 65546)
+ buf[5] = byte(EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) // typehigh
+ buf[6] = byte(EC_SUBTYPE_ROUTE_TARGET) // subtype
+ binary.BigEndian.PutUint32(buf[7:], 65546)
+ binary.BigEndian.PutUint16(buf[11:], 65000)
+ r = &RouteTargetMembershipNLRI{}
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1.10:65000", r.String())
+ buf, err = r.Serialize()
+ assert.Equal(nil, err)
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1.10:65000", r.String())
// OpaqueExtended
- buf = make([]byte, 12)
- binary.BigEndian.PutUint32(buf[:4], 65546)
- buf[4] = byte(EC_TYPE_TRANSITIVE_OPAQUE) // typehigh
- binary.BigEndian.PutUint32(buf[8:], 1000000)
- r.DecodeFromBytes(buf)
- assert.Equal("65546:1000000/96", r.String())
+ buf = make([]byte, 13)
+ binary.BigEndian.PutUint32(buf[1:5], 65546)
+ buf[5] = byte(EC_TYPE_TRANSITIVE_OPAQUE) // typehigh
+ binary.BigEndian.PutUint32(buf[9:], 1000000)
+ r = &RouteTargetMembershipNLRI{}
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1000000", r.String())
+ buf, err = r.Serialize()
+ assert.Equal(nil, err)
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1000000", r.String())
// Unknown
- buf = make([]byte, 12)
- binary.BigEndian.PutUint32(buf[:4], 65546)
- buf[4] = 0x04 // typehigh
- binary.BigEndian.PutUint32(buf[8:], 1000000)
- r.DecodeFromBytes(buf)
- assert.Equal("65546:1000000/96", r.String())
+ buf = make([]byte, 13)
+ binary.BigEndian.PutUint32(buf[1:5], 65546)
+ buf[5] = 0x04 // typehigh
+ binary.BigEndian.PutUint32(buf[9:], 1000000)
+ r = &RouteTargetMembershipNLRI{}
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1000000", r.String())
+ buf, err = r.Serialize()
+ assert.Equal(nil, err)
+ err = r.DecodeFromBytes(buf)
+ assert.Equal(nil, err)
+ assert.Equal("65546:1000000", r.String())
}