summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-11-15 11:58:17 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-11-21 10:56:23 +0900
commite3cadd768d891b3915fbdeda3e9c460ae6cba313 (patch)
treedfd4e203ceaf15ec14681aa39ef20bd3fadc6cc7
parent9ea6e5fb659436aad24eaab7ba93c70adf6b06a6 (diff)
packet/bgp: Zeros if GW in EVPN Prefix route omitted
According to "draft-ietf-bess-evpn-prefix-advertisement-08", the GW IP field SHOULD be zero if it is not used, but currently, GoBGP skips encoding the GW IP field (not composed). This patch fixes to fill zeros to solve this problem. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r--packet/bgp/bgp.go95
1 files changed, 51 insertions, 44 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index 2b3af3c6..a1f94c7d 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -2527,79 +2527,86 @@ type EVPNIPPrefixRoute struct {
}
func (er *EVPNIPPrefixRoute) DecodeFromBytes(data []byte) error {
- if len(data) < 30 { // rd + esi + etag + prefix-len + ipv4 addr + label
+ addrLen := net.IPv4len
+ switch len(data) {
+ case 34:
+ // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) + IPv4 Prefix(4) + GW IPv4(4) + Label(3)
+ case 58:
+ // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) + IPv6 Prefix(16) + GW IPv6(16) + Label(3)
+ addrLen = net.IPv6len
+ default:
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPN IP Prefix Route bytes available")
}
- er.RD = GetRouteDistinguisher(data)
- data = data[er.RD.Len():]
- err := er.ESI.DecodeFromBytes(data)
+
+ er.RD = GetRouteDistinguisher(data[0:8])
+
+ err := er.ESI.DecodeFromBytes(data[8:18])
if err != nil {
return err
}
- data = data[10:]
- er.ETag = binary.BigEndian.Uint32(data[0:4])
- data = data[4:]
- er.IPPrefixLength = data[0]
- addrLen := 4
- data = data[1:]
- if len(data) > 19 { // ipv6 addr + label
- addrLen = 16
- }
- er.IPPrefix = net.IP(data[:addrLen])
- data = data[addrLen:]
- switch {
- case len(data) == 3:
- er.Label = labelDecode(data)
- case len(data) == addrLen+3:
- er.GWIPAddress = net.IP(data[:addrLen])
- er.Label = labelDecode(data[addrLen:])
- default:
- return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPN IP Prefix Route bytes available")
+
+ er.ETag = binary.BigEndian.Uint32(data[18:22])
+
+ er.IPPrefixLength = data[22]
+
+ offset := 23 // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1)
+ er.IPPrefix = data[offset : offset+addrLen]
+ offset += addrLen
+
+ er.GWIPAddress = data[offset : offset+addrLen]
+ offset += addrLen
+
+ if er.Label, err = labelDecode(data[offset : offset+3]); err != nil {
+ return err
}
+ //offset += 3
+
return nil
}
func (er *EVPNIPPrefixRoute) Serialize() ([]byte, error) {
- var buf []byte
- var err error
+ buf := make([]byte, 23) // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1)
+
if er.RD != nil {
- buf, err = er.RD.Serialize()
+ tbuf, err := er.RD.Serialize()
if err != nil {
return nil, err
}
- } else {
- buf = make([]byte, 8)
+ copy(buf[0:8], tbuf)
}
+
tbuf, err := er.ESI.Serialize()
if err != nil {
return nil, err
}
- buf = append(buf, tbuf...)
+ copy(buf[8:18], tbuf)
- tbuf = make([]byte, 4)
- binary.BigEndian.PutUint32(tbuf, er.ETag)
- buf = append(buf, tbuf...)
+ binary.BigEndian.PutUint32(buf[18:22], er.ETag)
- buf = append(buf, er.IPPrefixLength)
+ buf[22] = er.IPPrefixLength
if er.IPPrefix == nil {
return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("IP Prefix is nil"))
} else if er.IPPrefix.To4() != nil {
- buf = append(buf, []byte(er.IPPrefix.To4())...)
+ buf = append(buf, er.IPPrefix.To4()...)
+ if er.GWIPAddress == nil {
+ // draft-ietf-bess-evpn-prefix-advertisement: IP Prefix Advertisement in EVPN
+ // The GW IP field SHOULD be zero if it is not used as an Overlay Index.
+ er.GWIPAddress = net.IPv4zero
+ }
+ buf = append(buf, er.GWIPAddress.To4()...)
} else {
- buf = append(buf, []byte(er.IPPrefix)...)
- }
-
- if er.GWIPAddress != nil {
- if er.GWIPAddress.To4() != nil {
- buf = append(buf, []byte(er.GWIPAddress.To4())...)
- } else {
- buf = append(buf, []byte(er.GWIPAddress.To16())...)
+ buf = append(buf, er.IPPrefix.To16()...)
+ if er.GWIPAddress == nil {
+ er.GWIPAddress = net.IPv6zero
}
+ buf = append(buf, er.GWIPAddress.To16()...)
}
- tbuf = make([]byte, 3)
- labelSerialize(er.Label, tbuf)
+ tbuf, err = labelSerialize(er.Label)
+ if err != nil {
+ return nil, err
+ }
buf = append(buf, tbuf...)
return buf, nil