diff options
-rw-r--r-- | packet/bgp/bgp.go | 35 | ||||
-rw-r--r-- | packet/bgp/bgp_test.go | 40 | ||||
-rw-r--r-- | table/destination_test.go | 1 |
3 files changed, 64 insertions, 12 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index b3472322..405469df 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -833,6 +833,10 @@ func NewIPAddrPrefix(length uint8, prefix string) *IPAddrPrefix { } } +func isIPv4MappedIPv6(ip net.IP) bool { + return len(ip) == net.IPv6len && ip.To4() != nil +} + type IPv6AddrPrefix struct { IPAddrPrefix } @@ -842,18 +846,11 @@ func (r *IPv6AddrPrefix) AFI() uint16 { } func (r *IPv6AddrPrefix) String() string { - isZero := func(p net.IP) bool { - for i := 0; i < len(p); i++ { - if p[i] != 0 { - return false - } - } - return true - }(r.Prefix[0:10]) - if isZero && r.Prefix[10] == 0xff && r.Prefix[11] == 0xff { - return fmt.Sprintf("::ffff:%s/%d", r.Prefix.String(), r.Length) + prefix := r.Prefix.String() + if isIPv4MappedIPv6(r.Prefix) { + prefix = "::ffff:" + prefix } - return fmt.Sprintf("%s/%d", r.Prefix.String(), r.Length) + return fmt.Sprintf("%s/%d", prefix, r.Length) } func NewIPv6AddrPrefix(length uint8, prefix string) *IPv6AddrPrefix { @@ -1379,7 +1376,21 @@ func (l *LabeledIPAddrPrefix) Serialize() ([]byte, error) { } func (l *LabeledIPAddrPrefix) String() string { - return fmt.Sprintf("%s/%d", l.Prefix.String(), int(l.Length)-l.Labels.Len()*8) + prefix := l.Prefix.String() + if isIPv4MappedIPv6(l.Prefix) { + prefix = "::ffff:" + prefix + } + return fmt.Sprintf("%s/%d", prefix, int(l.Length)-l.Labels.Len()*8) +} + +func (l *LabeledIPAddrPrefix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + Labels []uint32 `json:"labels"` + }{ + Prefix: l.String(), + Labels: l.Labels.Labels, + }) } func NewLabeledIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPAddrPrefix { diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go index 194dbf12..c46144cc 100644 --- a/packet/bgp/bgp_test.go +++ b/packet/bgp/bgp_test.go @@ -538,3 +538,43 @@ func Test_CompareFlowSpecNLRI(t *testing.T) { assert.Nil(err) assert.True(r < 0) } + +func Test_NLRIwithIPv4MappedIPv6prefix(t *testing.T) { + assert := assert.New(t) + n1 := NewIPv6AddrPrefix(120, "::ffff:10.0.0.1") + buf1, err := n1.Serialize() + assert.Nil(err) + n2, err := NewPrefixFromRouteFamily(RouteFamilyToAfiSafi(RF_IPv6_UC)) + assert.Nil(err) + err = n2.DecodeFromBytes(buf1) + assert.Nil(err) + buf2, _ := n2.Serialize() + if reflect.DeepEqual(n1, n2) { + t.Log("OK") + } else { + t.Error("Something wrong") + t.Error(len(buf1), n1, buf1) + t.Error(len(buf2), n2, buf2) + t.Log(bytes.Equal(buf1, buf2)) + } + + label := NewMPLSLabelStack(2) + + n3 := NewLabeledIPv6AddrPrefix(120, "::ffff:10.0.0.1", *label) + buf1, err = n3.Serialize() + assert.Nil(err) + n4, err := NewPrefixFromRouteFamily(RouteFamilyToAfiSafi(RF_IPv6_MPLS)) + assert.Nil(err) + err = n4.DecodeFromBytes(buf1) + assert.Nil(err) + buf2, _ = n3.Serialize() + t.Log(n3, n4) + if reflect.DeepEqual(n3, n4) { + t.Log("OK") + } else { + t.Error("Something wrong") + t.Error(len(buf1), n3, buf1) + t.Error(len(buf2), n4, buf2) + t.Log(bytes.Equal(buf1, buf2)) + } +} diff --git a/table/destination_test.go b/table/destination_test.go index 2778b8a4..7cace89e 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -399,6 +399,7 @@ func TestRadixkey(t *testing.T) { assert.Equal(t, "000010100000001100100000", CidrToRadixkey("10.3.32.0/24")) assert.Equal(t, "000010100000001100100000", IpToRadixkey(net.ParseIP("10.3.32.0").To4(), 24)) assert.Equal(t, "000010100000001100100000", IpToRadixkey(net.ParseIP("10.3.32.0").To4(), 24)) + assert.Equal(t, CidrToRadixkey("::ffff:0.0.0.0/96")+"000010100000001100100000", CidrToRadixkey("::ffff:10.3.32.0/120")) } func TestMultipath(t *testing.T) { |