summaryrefslogtreecommitdiffhomepage
path: root/packet
diff options
context:
space:
mode:
authorWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-09-27 14:54:20 +0000
committerWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-10-04 04:03:46 +0000
commitcda8d873fa0cc508ac8756a7da95f79253116aae (patch)
treea9beed8f597bbcb2bc9b7e7622ad594446c06906 /packet
parentbccb1c0c23ab57d9b94db3d07872ebb6c340f473 (diff)
packet/bgp: fix handling of IPv4 mapped IPv6 prefixes
closes #1117 Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'packet')
-rw-r--r--packet/bgp/bgp.go35
-rw-r--r--packet/bgp/bgp_test.go40
2 files changed, 63 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))
+ }
+}