diff options
-rw-r--r-- | packet/bgp.go | 116 | ||||
-rw-r--r-- | packet/bgp_test.go | 8 |
2 files changed, 93 insertions, 31 deletions
diff --git a/packet/bgp.go b/packet/bgp.go index 0c345ed2..fabcc44e 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -862,25 +862,38 @@ func getRouteDistinguisher(data []byte) RouteDistinguisherInterface { return rd } -func labelDecode(data []byte) uint32 { - return uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2]) -} - -func labelSerialize(label uint32, buf []byte) { - buf[0] = byte((label >> 16) & 0xff) - buf[1] = byte((label >> 8) & 0xff) - buf[2] = byte(label & 0xff) -} +// +// RFC3107 Carrying Label Information in BGP-4 +// +// 4. Carrying Label Mapping Information +// +// b) Label: +// +// The Label field carries one or more labels (that corresponds to +// the stack of labels [MPLS-ENCAPS(RFC3032)]). Each label is encoded as +// 4 octets, where the high-order 20 bits contain the label value, and +// the low order bit contains "Bottom of Stack" +// +// RFC3032 MPLS Label Stack Encoding +// +// 2.1. Encoding the Label Stack +// +// 0 1 2 3 +// 0 ... 9 0 ... 9 0 1 2 3 4 ... 9 0 1 +// +-----+-+-+---+-+-+-+-+-+-----+-+-+-+ +// | Label | Exp |S| TTL | +// +-----+-+-+---+-+-+-+-+-+-----+-+-+-+ +// -type Label struct { +type MPLSLabelStack struct { Labels []uint32 } -func (l *Label) DecodeFromBytes(data []byte) error { +func (l *MPLSLabelStack) DecodeFromBytes(data []byte) error { labels := []uint32{} foundBottom := false - for len(data) >= 4 { - label := uint32(data[0]<<16 | data[1]<<8 | data[2]) + for len(data) >= 3 { + label := uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2]) data = data[3:] labels = append(labels, label>>4) if label&1 == 1 { @@ -896,7 +909,7 @@ func (l *Label) DecodeFromBytes(data []byte) error { return nil } -func (l *Label) Serialize() ([]byte, error) { +func (l *MPLSLabelStack) Serialize() ([]byte, error) { buf := make([]byte, len(l.Labels)*3) for i, label := range l.Labels { label = label << 4 @@ -908,15 +921,39 @@ func (l *Label) Serialize() ([]byte, error) { return buf, nil } -func (l *Label) Len() int { return 3 * len(l.Labels) } +func (l *MPLSLabelStack) Len() int { return 3 * len(l.Labels) } -func NewLabel(labels ...uint32) *Label { - return &Label{labels} +func NewMPLSLabelStack(labels ...uint32) *MPLSLabelStack { + return &MPLSLabelStack{labels} } +// +// RFC3107 Carrying Label Information in BGP-4 +// +// 3. Carrying Label Mapping Information +// +// +----------------------+ +// | Length (1 octet) | +// +----------------------+ +// | Label (3 octets) | +// +----------------------+ +// ....................... +// +----------------------+ +// | Prefix (variable) | +// +----------------------+ +// +// RFC4364 BGP/MPLS IP VPNs +// +// 4.3.4. How VPN-IPv4 NLRI Is Carried in BGP +// +// The labeled VPN-IPv4 NLRI itself is encoded as specified in +// [MPLS-BGP(RFC3107)], where the prefix consists of an 8-byte RD +// followed by an IPv4 prefix. +// + type LabelledVPNIPAddrPrefix struct { IPAddrPrefixDefault - Labels Label + Labels MPLSLabelStack RD RouteDistinguisherInterface addrlen uint8 } @@ -973,7 +1010,7 @@ func (l *LabelledVPNIPAddrPrefix) ToApiStruct() *api.Nlri { } } -func NewLabelledVPNIPAddrPrefix(length uint8, prefix string, label Label, rd RouteDistinguisherInterface) *LabelledVPNIPAddrPrefix { +func NewLabelledVPNIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabelledVPNIPAddrPrefix { rdlen := 0 if rd != nil { rdlen = rd.Len() @@ -994,7 +1031,7 @@ func (l *LabelledVPNIPv6AddrPrefix) AFI() uint16 { return AFI_IP6 } -func NewLabelledVPNIPv6AddrPrefix(length uint8, prefix string, label Label, rd RouteDistinguisherInterface) *LabelledVPNIPv6AddrPrefix { +func NewLabelledVPNIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabelledVPNIPv6AddrPrefix { rdlen := 0 if rd != nil { rdlen = rd.Len() @@ -1011,7 +1048,7 @@ func NewLabelledVPNIPv6AddrPrefix(length uint8, prefix string, label Label, rd R type LabelledIPAddrPrefix struct { IPAddrPrefixDefault - Labels Label + Labels MPLSLabelStack addrlen uint8 } @@ -1079,7 +1116,7 @@ func (l *LabelledIPAddrPrefix) Serialize() ([]byte, error) { return buf, nil } -func NewLabelledIPAddrPrefix(length uint8, prefix string, label Label) *LabelledIPAddrPrefix { +func NewLabelledIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabelledIPAddrPrefix { return &LabelledIPAddrPrefix{ IPAddrPrefixDefault{length + uint8(label.Len()*8), net.ParseIP(prefix)}, label, @@ -1091,7 +1128,7 @@ type LabelledIPv6AddrPrefix struct { LabelledIPAddrPrefix } -func NewLabelledIPv6AddrPrefix(length uint8, prefix string, label Label) *LabelledIPv6AddrPrefix { +func NewLabelledIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabelledIPv6AddrPrefix { return &LabelledIPv6AddrPrefix{ LabelledIPAddrPrefix{ IPAddrPrefixDefault{length + uint8(label.Len()*8), net.ParseIP(prefix)}, @@ -1250,6 +1287,31 @@ func (esi *EthernetSegmentIdentifier) String() string { return s.String() } +// +// I-D bess-evpn-overlay-01 +// +// 5.1.3 Constructing EVPN BGP Routes +// +// For the balance of this memo, the MPLS label field will be +// referred to as the VNI/VSID field. The VNI/VSID field is used for +// both local and global VNIs/VSIDs, and for either case the entire 24- +// bit field is used to encode the VNI/VSID value. +// +// We can't use type MPLSLabelStack for EVPN NLRI, because EVPN NLRI's MPLS +// field can be filled with VXLAN VNI. In that case, we must avoid modifying +// bottom of stack bit. +// + +func labelDecode(data []byte) uint32 { + return uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2]) +} + +func labelSerialize(label uint32, buf []byte) { + buf[0] = byte((label >> 16) & 0xff) + buf[1] = byte((label >> 8) & 0xff) + buf[2] = byte(label & 0xff) +} + type EVPNEthernetAutoDiscoveryRoute struct { RD RouteDistinguisherInterface ESI EthernetSegmentIdentifier @@ -1708,13 +1770,13 @@ func NewPrefixFromRouteFamily(afi uint16, safi uint8) (prefix AddrPrefixInterfac case RF_IPv6_UC, RF_IPv6_MC: prefix = NewIPv6AddrPrefix(0, "") case RF_IPv4_VPN: - prefix = NewLabelledVPNIPAddrPrefix(0, "", *NewLabel(), nil) + prefix = NewLabelledVPNIPAddrPrefix(0, "", *NewMPLSLabelStack(), nil) case RF_IPv6_VPN: - prefix = NewLabelledVPNIPv6AddrPrefix(0, "", *NewLabel(), nil) + prefix = NewLabelledVPNIPv6AddrPrefix(0, "", *NewMPLSLabelStack(), nil) case RF_IPv4_MPLS: - prefix = NewLabelledIPAddrPrefix(0, "", *NewLabel()) + prefix = NewLabelledIPAddrPrefix(0, "", *NewMPLSLabelStack()) case RF_IPv6_MPLS: - prefix = NewLabelledIPv6AddrPrefix(0, "", *NewLabel()) + prefix = NewLabelledIPv6AddrPrefix(0, "", *NewMPLSLabelStack()) case RF_EVPN: prefix = NewEVPNNLRI(0, 0, nil) case RF_RTC_UC: diff --git a/packet/bgp_test.go b/packet/bgp_test.go index 90ad7d20..16055819 100644 --- a/packet/bgp_test.go +++ b/packet/bgp_test.go @@ -69,9 +69,9 @@ func update() *BGPMessage { } mp_nlri := []AddrPrefixInterface{ - NewLabelledVPNIPAddrPrefix(20, "192.0.9.0", *NewLabel(1, 2, 3), + NewLabelledVPNIPAddrPrefix(20, "192.0.9.0", *NewMPLSLabelStack(1, 2, 3), NewRouteDistinguisherTwoOctetAS(256, 10000)), - NewLabelledVPNIPAddrPrefix(26, "192.10.8.192", *NewLabel(5, 6, 7, 8), + NewLabelledVPNIPAddrPrefix(26, "192.10.8.192", *NewMPLSLabelStack(5, 6, 7, 8), NewRouteDistinguisherIPAddressAS("10.0.1.1", 10001)), } @@ -79,11 +79,11 @@ func update() *BGPMessage { "fe80:1234:1234:5667:8967:af12:8912:1023")} mp_nlri3 := []AddrPrefixInterface{NewLabelledVPNIPv6AddrPrefix(100, - "fe80:1234:1234:5667:8967:af12:1203:33a1", *NewLabel(5, 6), + "fe80:1234:1234:5667:8967:af12:1203:33a1", *NewMPLSLabelStack(5, 6), NewRouteDistinguisherFourOctetAS(5, 6))} mp_nlri4 := []AddrPrefixInterface{NewLabelledIPAddrPrefix(25, "192.168.0.0", - *NewLabel(5, 6, 7))} + *NewMPLSLabelStack(5, 6, 7))} mac, _ := net.ParseMAC("01:23:45:67:89:ab") mp_nlri5 := []AddrPrefixInterface{ |