summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packet/bgp/bgp.go20
-rw-r--r--packet/bgp/bgp_test.go34
2 files changed, 44 insertions, 10 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index a911c411..3afb7a9e 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -5189,20 +5189,20 @@ func (p *PathAttributeMpReachNLRI) DecodeFromBytes(data []byte) error {
}
nexthopbin := value[4 : 4+nexthoplen]
if nexthoplen > 0 {
- addrlen := 4
- if afi == AFI_IP6 {
- addrlen = 16
- }
+ v4addrlen := 4
+ v6addrlen := 16
offset := 0
if safi == SAFI_MPLS_VPN {
offset = 8
}
switch nexthoplen {
- case 2 * (offset + addrlen):
- p.LinkLocalNexthop = nexthopbin[offset+addrlen+offset : 2*(offset+addrlen)]
+ case 2 * (offset + v6addrlen):
+ p.LinkLocalNexthop = nexthopbin[offset+v6addrlen+offset : 2*(offset+v6addrlen)]
fallthrough
- case offset + addrlen:
- p.Nexthop = nexthopbin[offset : offset+addrlen]
+ case offset + v6addrlen:
+ p.Nexthop = nexthopbin[offset : offset+v6addrlen]
+ case offset + v4addrlen:
+ p.Nexthop = nexthopbin[offset : offset+v4addrlen]
default:
return NewMessageError(eCode, eSubCode, value, "mpreach nexthop length is incorrect")
}
@@ -5235,7 +5235,7 @@ func (p *PathAttributeMpReachNLRI) Serialize() ([]byte, error) {
afi := p.AFI
safi := p.SAFI
nexthoplen := 4
- if afi == AFI_IP6 {
+ if afi == AFI_IP6 || p.Nexthop.To4() == nil {
nexthoplen = 16
}
offset := 0
@@ -5254,7 +5254,7 @@ func (p *PathAttributeMpReachNLRI) Serialize() ([]byte, error) {
buf[2] = safi
buf[3] = uint8(nexthoplen)
if nexthoplen != 0 {
- if afi == AFI_IP6 {
+ if p.Nexthop.To4() == nil {
copy(buf[4+offset:], p.Nexthop.To16())
if p.LinkLocalNexthop != nil {
copy(buf[4+offset+16:], p.LinkLocalNexthop.To16())
diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go
index e0f1a5ca..e6d38873 100644
--- a/packet/bgp/bgp_test.go
+++ b/packet/bgp/bgp_test.go
@@ -739,3 +739,37 @@ func Test_MpReachNLRIWithVPNv6Prefix(t *testing.T) {
// Test serialised value
assert.Equal(bufin, bufout)
}
+
+func Test_MpReachNLRIWithIPv4PrefixWithIPv6Nexthop(t *testing.T) {
+ assert := assert.New(t)
+ bufin := []byte{
+ 0x80, 0x0e, 0x19, // flags(1), type(1), length(1)
+ 0x00, 0x01, 0x01, 0x10, // afi(1), safi(1), nexthoplen(1)
+ 0x20, 0x01, 0x0d, 0xb8, // nexthop(32)
+ 0x00, 0x01, 0x00, 0x00, // = "2001:db8:1::1"
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, // reserved(1)
+ 0x18, 0xc0, 0xa8, 0x0a, // nlri(7)
+ }
+ // Test DecodeFromBytes()
+ p := &PathAttributeMpReachNLRI{}
+ err := p.DecodeFromBytes(bufin)
+ assert.Nil(err)
+ // Test decoded values
+ assert.Equal(BGPAttrFlag(0x80), p.Flags)
+ assert.Equal(BGPAttrType(0xe), p.Type)
+ assert.Equal(uint16(0x19), p.Length)
+ assert.Equal(uint16(AFI_IP), p.AFI)
+ assert.Equal(uint8(SAFI_UNICAST), p.SAFI)
+ assert.Equal(net.ParseIP("2001:db8:1::1"), p.Nexthop)
+ value := []AddrPrefixInterface{
+ NewIPAddrPrefix(24, "192.168.10.0"),
+ }
+ assert.Equal(value, p.Value)
+ // Test Serialize()
+ bufout, err := p.Serialize()
+ assert.Nil(err)
+ // Test serialised value
+ assert.Equal(bufin, bufout)
+}