diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 7c6fb5824..80ca164d8 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -84,14 +84,15 @@ const ( BGP_ASPATH_ATTR_TYPE_CONFED_SET = 4 ) +// ExtendedCommunityAttrType shows the BGP Extended Community Types. // RFC7153 5.1. Registries for the "Type" Field -// RANGE REGISTRATION PROCEDURES -// 0x00-0x3F Transitive First Come First Served -// 0x40-0x7F Non-Transitive First Come First Served -// 0x80-0x8F Transitive Experimental Use -// 0x90-0xBF Transitive Standards Action -// 0xC0-0xCF Non-Transitive Experimental Use -// 0xD0-0xFF Non-Transitive Standards Action +// RANGE REGISTRATION PROCEDURES +// 0x00-0x3F Transitive First Come First Served +// 0x40-0x7F Non-Transitive First Come First Served +// 0x80-0x8F Transitive Experimental Use +// 0x90-0xBF Transitive Standards Action +// 0xC0-0xCF Non-Transitive Experimental Use +// 0xD0-0xFF Non-Transitive Standards Action type ExtendedCommunityAttrType uint8 const ( @@ -115,10 +116,11 @@ const ( EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3 ExtendedCommunityAttrType = 0x82 // RFC7674 ) +// ExtendedCommunityAttrSubType shows the BGP Extended Community Sub-Types. // RFC7153 5.2. Registries for the "Sub-Type" Field -// RANGE REGISTRATION PROCEDURES -// 0x00-0xBF First Come First Served -// 0xC0-0xFF IETF Review +// RANGE REGISTRATION PROCEDURES +// 0x00-0xBF First Come First Served +// 0xC0-0xFF IETF Review type ExtendedCommunityAttrSubType uint8 const ( @@ -784,7 +786,7 @@ func (c *CapLongLivedGracefulRestart) DecodeFromBytes(data []byte) error { valueLen := int(c.CapLen) if valueLen%7 != 0 || len(data) < valueLen { - return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "invalid length of long lived graceful restart capablity") + return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "invalid length of long lived graceful restart capability") } for i := valueLen; i >= 7; i -= 7 { t := &CapLongLivedGracefulRestartTuple{ @@ -1046,7 +1048,10 @@ func (p *PrefixDefault) SetPathLocalIdentifier(id uint32) { p.localId = id } -func (p *PrefixDefault) decodePathIdentifier(data []byte) ([]byte, error) { +func (p *PrefixDefault) decodePathIdentifier(data []byte, rf RouteFamily, options []*MarshallingOption) ([]byte, error) { + if !IsAddPathEnabled(true, rf, options) { + return data, nil + } if len(data) < 4 { code := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) subcode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) @@ -1056,57 +1061,72 @@ func (p *PrefixDefault) decodePathIdentifier(data []byte) ([]byte, error) { return data[4:], nil } -func (p *PrefixDefault) serializeIdentifier() ([]byte, error) { +func (p *PrefixDefault) serializeIdentifier(rf RouteFamily, options []*MarshallingOption) ([]byte, error) { + if !IsAddPathEnabled(false, rf, options) { + return nil, nil + } buf := make([]byte, 4) binary.BigEndian.PutUint32(buf, p.PathLocalIdentifier()) return buf, nil } -type IPAddrPrefixDefault struct { - PrefixDefault - Length uint8 - Prefix net.IP -} - -func (r *IPAddrPrefixDefault) decodePrefix(data []byte, bitlen uint8, addrlen uint8) error { - bytelen := (int(bitlen) + 7) / 8 - if len(data) < bytelen { +func decodeIPAddrPrefix(data []byte, bitLen uint8, addrLen int) (net.IP, error) { + byteLen := (int(bitLen) + 7) / 8 + if len(data) < byteLen { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) - return NewMessageError(eCode, eSubCode, nil, "network bytes is short") + return nil, NewMessageError(eCode, eSubCode, nil, "invalid ip prefix byte length") } - b := make([]byte, addrlen) - copy(b, data[:bytelen]) - r.Prefix = b - return nil + prefix := make(net.IP, addrLen) + copy(prefix, data[:byteLen]) + return prefix, nil } -func (r *IPAddrPrefixDefault) serializePrefix(bitLen uint8) ([]byte, error) { +func serializeIPAddrPrefix(prefix net.IP, bitLen uint8) (net.IP, []byte, error) { byteLen := (int(bitLen) + 7) / 8 buf := make([]byte, byteLen) - copy(buf, r.Prefix) - // clear trailing bits in the last byte. rfc doesn't require - // this though. + copy(buf, prefix) + // Clear trailing bits in the last byte. rfc doesn't require this though. rem := bitLen % 8 if rem != 0 { mask := 0xff00 >> rem lastByte := buf[byteLen-1] & byte(mask) buf[byteLen-1] = lastByte } - r.Prefix = make([]byte, len(r.Prefix)) - copy(r.Prefix, buf) - return buf, nil + prefix = make([]byte, len(prefix)) + copy(prefix, buf) + return prefix, buf, nil } -func (r *IPAddrPrefixDefault) Len(options ...*MarshallingOption) int { +type ipAddrPrefix struct { + PrefixDefault + Length uint8 + Prefix net.IP +} + +func (r *ipAddrPrefix) decodePrefix(data []byte, bitLen uint8) (err error) { + r.Prefix, err = decodeIPAddrPrefix(data, bitLen, net.IPv4len) + return err +} + +func (r *ipAddrPrefix) serializePrefix(bitLen uint8) (buf []byte, err error) { + r.Prefix, buf, err = serializeIPAddrPrefix(r.Prefix, bitLen) + return buf, err +} + +func (r *ipAddrPrefix) AFI() uint16 { + return AFI_IP +} + +func (r *ipAddrPrefix) Len(options ...*MarshallingOption) int { return 1 + ((int(r.Length) + 7) / 8) } -func (r *IPAddrPrefixDefault) String() string { +func (r *ipAddrPrefix) String() string { return fmt.Sprintf("%s/%d", r.Prefix.String(), r.Length) } -func (r *IPAddrPrefixDefault) MarshalJSON() ([]byte, error) { +func (r *ipAddrPrefix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Prefix string `json:"prefix"` }{ @@ -1114,25 +1134,58 @@ func (r *IPAddrPrefixDefault) MarshalJSON() ([]byte, error) { }) } -type IPAddrPrefix struct { - IPAddrPrefixDefault - addrlen uint8 +type ipv6AddrPrefix struct { + PrefixDefault + Length uint8 + Prefix net.IP } -func (r *IPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - if r.addrlen == 0 { - r.addrlen = 4 - } - f := RF_IPv4_UC - if r.addrlen == 16 { - f = RF_IPv6_UC +func (r *ipv6AddrPrefix) decodePrefix(data []byte, bitLen uint8) (err error) { + r.Prefix, err = decodeIPAddrPrefix(data, bitLen, net.IPv6len) + return err +} + +func (r *ipv6AddrPrefix) serializePrefix(bitLen uint8) (buf []byte, err error) { + r.Prefix, buf, err = serializeIPAddrPrefix(r.Prefix, bitLen) + return buf, err +} + +func (r *ipv6AddrPrefix) AFI() uint16 { + return AFI_IP6 +} + +func (r *ipv6AddrPrefix) Len(options ...*MarshallingOption) int { + return 1 + ((int(r.Length) + 7) / 8) +} + +func isIPv4MappedIPv6(ip net.IP) bool { + return len(ip) == net.IPv6len && ip.To4() != nil +} + +func (r *ipv6AddrPrefix) String() string { + prefix := r.Prefix.String() + if isIPv4MappedIPv6(r.Prefix) { + prefix = "::ffff:" + prefix } - if IsAddPathEnabled(true, f, options) { - var err error - data, err = r.decodePathIdentifier(data) - if err != nil { - return err - } + return fmt.Sprintf("%s/%d", prefix, r.Length) +} + +func (r *ipv6AddrPrefix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + }{ + Prefix: r.String(), + }) +} + +type IPAddrPrefix struct { + ipAddrPrefix +} + +func (r *IPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) (err error) { + data, err = r.decodePathIdentifier(data, RF_IPv4_UC, options) + if err != nil { + return err } if len(data) < 1 { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) @@ -1140,21 +1193,13 @@ func (r *IPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOptio return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") } r.Length = data[0] - return r.decodePrefix(data[1:], r.Length, r.addrlen) + return r.decodePrefix(data[1:], r.Length) } func (r *IPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { - f := RF_IPv4_UC - if r.addrlen == 16 { - f = RF_IPv6_UC - } - var buf []byte - if IsAddPathEnabled(false, f, options) { - var err error - buf, err = r.serializeIdentifier() - if err != nil { - return nil, err - } + buf, err := r.serializeIdentifier(RF_IPv4_UC, options) + if err != nil { + return nil, err } buf = append(buf, r.Length) pbuf, err := r.serializePrefix(r.Length) @@ -1164,52 +1209,59 @@ func (r *IPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) return append(buf, pbuf...), nil } -func (r *IPAddrPrefix) AFI() uint16 { - return AFI_IP -} - func (r *IPAddrPrefix) SAFI() uint8 { return SAFI_UNICAST } func NewIPAddrPrefix(length uint8, prefix string) *IPAddrPrefix { return &IPAddrPrefix{ - IPAddrPrefixDefault{ + ipAddrPrefix: ipAddrPrefix{ Length: length, Prefix: net.ParseIP(prefix).To4(), }, - 4, } } -func isIPv4MappedIPv6(ip net.IP) bool { - return len(ip) == net.IPv6len && ip.To4() != nil -} - type IPv6AddrPrefix struct { - IPAddrPrefix + ipv6AddrPrefix } -func (r *IPv6AddrPrefix) AFI() uint16 { - return AFI_IP6 +func (r *IPv6AddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) (err error) { + data, err = r.decodePathIdentifier(data, RF_IPv6_UC, options) + if err != nil { + return err + } + if len(data) < 1 { + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") + } + r.Length = data[0] + return r.decodePrefix(data[1:], r.Length) } -func (r *IPv6AddrPrefix) String() string { - prefix := r.Prefix.String() - if isIPv4MappedIPv6(r.Prefix) { - prefix = "::ffff:" + prefix +func (r *IPv6AddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { + buf, err := r.serializeIdentifier(RF_IPv4_UC, options) + if err != nil { + return nil, err } - return fmt.Sprintf("%s/%d", prefix, r.Length) + buf = append(buf, r.Length) + pbuf, err := r.serializePrefix(r.Length) + if err != nil { + return nil, err + } + return append(buf, pbuf...), nil +} + +func (r *IPv6AddrPrefix) SAFI() uint8 { + return SAFI_UNICAST } func NewIPv6AddrPrefix(length uint8, prefix string) *IPv6AddrPrefix { return &IPv6AddrPrefix{ - IPAddrPrefix{ - IPAddrPrefixDefault{ - Length: length, - Prefix: net.ParseIP(prefix), - }, - 16, + ipv6AddrPrefix: ipv6AddrPrefix{ + Length: length, + Prefix: net.ParseIP(prefix), }, } } @@ -1462,8 +1514,10 @@ func ParseRouteDistinguisher(rd string) (RouteDistinguisherInterface, error) { // // The label information carried (as part of NLRI) in the Withdrawn // Routes field should be set to 0x800000. -const WITHDRAW_LABEL = uint32(0x800000) -const ZERO_LABEL = uint32(0) // some platform uses this as withdraw label +const ( + WITHDRAW_LABEL uint32 = 0x800000 + ZERO_LABEL uint32 = 0 // some platform uses this as withdraw label +) type MPLSLabelStack struct { Labels []uint32 @@ -1577,218 +1631,244 @@ ERR: // followed by an IPv4 prefix. // +type labeledVPNPrefix struct { + Labels MPLSLabelStack + RD RouteDistinguisherInterface +} + +func (l *labeledVPNPrefix) SAFI() uint8 { + return SAFI_MPLS_VPN +} + type LabeledVPNIPAddrPrefix struct { - IPAddrPrefixDefault - Labels MPLSLabelStack - RD RouteDistinguisherInterface - addrlen uint8 + ipAddrPrefix + labeledVPNPrefix +} + +func (l *LabeledVPNIPAddrPrefix) PrefixLen() uint8 { + return l.Length - uint8((l.Labels.Len()+l.RD.Len())*8) } func (l *LabeledVPNIPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - f := RF_IPv4_VPN - if l.addrlen == 16 { - f = RF_IPv6_VPN - } - if IsAddPathEnabled(true, f, options) { - var err error - data, err = l.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := l.decodePathIdentifier(data, RF_IPv4_VPN, options) + if err != nil { + return err } if len(data) < 1 { - return NewMessageError(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), nil, "prefix misses length field") + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") } l.Length = uint8(data[0]) data = data[1:] - l.Labels.DecodeFromBytes(data) - if int(l.Length)-8*(l.Labels.Len()) < 0 { - l.Labels.Labels = []uint32{} + err = l.Labels.DecodeFromBytes(data) + if err != nil { + return err } data = data[l.Labels.Len():] l.RD = GetRouteDistinguisher(data) + if err != nil { + return err + } data = data[l.RD.Len():] - restbits := int(l.Length) - 8*(l.Labels.Len()+l.RD.Len()) - return l.decodePrefix(data, uint8(restbits), l.addrlen) + return l.decodePrefix(data, l.PrefixLen()) } func (l *LabeledVPNIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { - f := RF_IPv4_VPN - if l.addrlen == 16 { - f = RF_IPv6_VPN - } - var buf []byte - if IsAddPathEnabled(false, f, options) { - var err error - buf, err = l.serializeIdentifier() - if err != nil { - return nil, err - } + buf, err := l.serializeIdentifier(RF_IPv4_VPN, options) + if err != nil { + return nil, err } buf = append(buf, l.Length) - lbuf, err := l.Labels.Serialize() + lBuf, err := l.Labels.Serialize() if err != nil { return nil, err } - buf = append(buf, lbuf...) - rbuf, err := l.RD.Serialize() + buf = append(buf, lBuf...) + rdBuf, err := l.RD.Serialize() if err != nil { return nil, err } - buf = append(buf, rbuf...) - restbits := int(l.Length) - 8*(l.Labels.Len()+l.RD.Len()) - pbuf, err := l.serializePrefix(uint8(restbits)) + buf = append(buf, rdBuf...) + pBuf, err := l.serializePrefix(l.PrefixLen()) if err != nil { return nil, err } - buf = append(buf, pbuf...) - return buf, nil -} - -func (l *LabeledVPNIPAddrPrefix) AFI() uint16 { - return AFI_IP + return append(buf, pBuf...), nil } -func (l *LabeledVPNIPAddrPrefix) SAFI() uint8 { - return SAFI_MPLS_VPN +func (l *LabeledVPNIPAddrPrefix) IPPrefix() string { + return fmt.Sprintf("%s/%d", l.Prefix, l.PrefixLen()) } func (l *LabeledVPNIPAddrPrefix) String() string { return fmt.Sprintf("%s:%s", l.RD, l.IPPrefix()) } -func (l *LabeledVPNIPAddrPrefix) IPPrefix() string { - masklen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) - return fmt.Sprintf("%s/%d", l.IPAddrPrefixDefault.Prefix, masklen) -} - func (l *LabeledVPNIPAddrPrefix) MarshalJSON() ([]byte, error) { - masklen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) return json.Marshal(struct { Prefix string `json:"prefix"` Labels []uint32 `json:"labels"` RD RouteDistinguisherInterface `json:"rd"` }{ - Prefix: fmt.Sprintf("%s/%d", l.IPAddrPrefixDefault.Prefix, masklen), + Prefix: l.IPPrefix(), Labels: l.Labels.Labels, RD: l.RD, }) } -func NewLabeledVPNIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPAddrPrefix { - rdlen := 0 +func NewLabeledVPNIPAddrPrefix(length uint8, prefix string, labels MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPAddrPrefix { + rdLen := 0 if rd != nil { - rdlen = rd.Len() + rdLen = rd.Len() } return &LabeledVPNIPAddrPrefix{ - IPAddrPrefixDefault{ - Length: length + uint8(8*(label.Len()+rdlen)), + ipAddrPrefix: ipAddrPrefix{ + Length: length + uint8(8*(labels.Len()+rdLen)), Prefix: net.ParseIP(prefix).To4(), }, - label, - rd, - 4, + labeledVPNPrefix: labeledVPNPrefix{ + Labels: labels, + RD: rd, + }, } } type LabeledVPNIPv6AddrPrefix struct { - LabeledVPNIPAddrPrefix + ipv6AddrPrefix + labeledVPNPrefix } -func (l *LabeledVPNIPv6AddrPrefix) AFI() uint16 { - return AFI_IP6 +func (l *LabeledVPNIPv6AddrPrefix) PrefixLen() uint8 { + return l.Length - uint8((l.Labels.Len()+l.RD.Len())*8) } -func NewLabeledVPNIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPv6AddrPrefix { - rdlen := 0 +func (l *LabeledVPNIPv6AddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { + data, err := l.decodePathIdentifier(data, RF_IPv6_VPN, options) + if err != nil { + return err + } + if len(data) < 1 { + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") + } + l.Length = uint8(data[0]) + data = data[1:] + err = l.Labels.DecodeFromBytes(data) + if err != nil { + return err + } + data = data[l.Labels.Len():] + l.RD = GetRouteDistinguisher(data) + if err != nil { + return err + } + data = data[l.RD.Len():] + return l.decodePrefix(data, l.PrefixLen()) +} + +func (l *LabeledVPNIPv6AddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { + buf, err := l.serializeIdentifier(RF_IPv6_VPN, options) + if err != nil { + return nil, err + } + buf = append(buf, l.Length) + lBuf, err := l.Labels.Serialize() + if err != nil { + return nil, err + } + buf = append(buf, lBuf...) + rdBuf, err := l.RD.Serialize() + if err != nil { + return nil, err + } + buf = append(buf, rdBuf...) + pBuf, err := l.serializePrefix(l.PrefixLen()) + if err != nil { + return nil, err + } + return append(buf, pBuf...), nil +} + +func (l *LabeledVPNIPv6AddrPrefix) IPPrefix() string { + return fmt.Sprintf("%s/%d", l.Prefix, l.PrefixLen()) +} + +func (l *LabeledVPNIPv6AddrPrefix) String() string { + return fmt.Sprintf("%s:%s", l.RD, l.IPPrefix()) +} + +func NewLabeledVPNIPv6AddrPrefix(length uint8, prefix string, labels MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPv6AddrPrefix { + rdLen := 0 if rd != nil { - rdlen = rd.Len() + rdLen = rd.Len() } return &LabeledVPNIPv6AddrPrefix{ - LabeledVPNIPAddrPrefix{ - IPAddrPrefixDefault{ - Length: length + uint8(8*(label.Len()+rdlen)), - Prefix: net.ParseIP(prefix), - }, - label, - rd, - 16, + ipv6AddrPrefix: ipv6AddrPrefix{ + Length: length + uint8(8*(labels.Len()+rdLen)), + Prefix: net.ParseIP(prefix).To16(), + }, + labeledVPNPrefix: labeledVPNPrefix{ + Labels: labels, + RD: rd, }, } } -type LabeledIPAddrPrefix struct { - IPAddrPrefixDefault - Labels MPLSLabelStack - addrlen uint8 +type labeledPrefix struct { + Labels MPLSLabelStack } -func (r *LabeledIPAddrPrefix) AFI() uint16 { - return AFI_IP +func (l *labeledPrefix) SAFI() uint8 { + return SAFI_MPLS_LABEL } -func (r *LabeledIPAddrPrefix) SAFI() uint8 { - return SAFI_MPLS_LABEL +type LabeledIPAddrPrefix struct { + ipAddrPrefix + labeledPrefix } +func (l *LabeledIPAddrPrefix) PrefixLen() uint8 { + return l.Length - uint8(l.Labels.Len()*8) +} func (l *LabeledIPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - f := RF_IPv4_MPLS - if l.addrlen == 16 { - f = RF_IPv6_MPLS + data, err := l.decodePathIdentifier(data, RF_IPv4_MPLS, options) + if err != nil { + return err } - if IsAddPathEnabled(true, f, options) { - var err error - data, err = l.decodePathIdentifier(data) - if err != nil { - return err - } + if len(data) < 1 { + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") } l.Length = uint8(data[0]) data = data[1:] - l.Labels.DecodeFromBytes(data) - if int(l.Length)-8*(l.Labels.Len()) < 0 { - l.Labels.Labels = []uint32{} + err = l.Labels.DecodeFromBytes(data) + if err != nil { + return err } - restbits := int(l.Length) - 8*(l.Labels.Len()) data = data[l.Labels.Len():] - l.decodePrefix(data, uint8(restbits), l.addrlen) + l.decodePrefix(data, l.PrefixLen()) return nil } func (l *LabeledIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { - f := RF_IPv4_MPLS - if l.addrlen == 16 { - f = RF_IPv6_MPLS - } - var buf []byte - if IsAddPathEnabled(false, f, options) { - var err error - buf, err = l.serializeIdentifier() - if err != nil { - return nil, err - } + buf, err := l.serializeIdentifier(RF_IPv4_MPLS, options) + if err != nil { + return nil, err } buf = append(buf, l.Length) - restbits := int(l.Length) - 8*(l.Labels.Len()) - lbuf, err := l.Labels.Serialize() + lBuf, err := l.Labels.Serialize() if err != nil { return nil, err } - buf = append(buf, lbuf...) - pbuf, err := l.serializePrefix(uint8(restbits)) + buf = append(buf, lBuf...) + pBuf, err := l.serializePrefix(l.PrefixLen()) if err != nil { return nil, err } - buf = append(buf, pbuf...) - return buf, nil -} - -func (l *LabeledIPAddrPrefix) String() string { - prefix := l.Prefix.String() - if isIPv4MappedIPv6(l.Prefix) { - prefix = "::ffff:" + prefix - } - return fmt.Sprintf("%s/%d", prefix, int(l.Length)-l.Labels.Len()*8) + return append(buf, pBuf...), nil } func (l *LabeledIPAddrPrefix) MarshalJSON() ([]byte, error) { @@ -1801,34 +1881,83 @@ func (l *LabeledIPAddrPrefix) MarshalJSON() ([]byte, error) { }) } -func NewLabeledIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPAddrPrefix { +func NewLabeledIPAddrPrefix(length uint8, prefix string, labels MPLSLabelStack) *LabeledIPAddrPrefix { return &LabeledIPAddrPrefix{ - IPAddrPrefixDefault{ - Length: length + uint8(label.Len()*8), + ipAddrPrefix: ipAddrPrefix{ + Length: length + uint8(labels.Len()*8), Prefix: net.ParseIP(prefix).To4(), }, - label, - 4, + labeledPrefix: labeledPrefix{ + Labels: labels, + }, } } type LabeledIPv6AddrPrefix struct { - LabeledIPAddrPrefix + ipv6AddrPrefix + labeledPrefix } -func (l *LabeledIPv6AddrPrefix) AFI() uint16 { - return AFI_IP6 +func (l *LabeledIPv6AddrPrefix) PrefixLen() uint8 { + return l.Length - uint8(l.Labels.Len()*8) +} +func (l *LabeledIPv6AddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { + data, err := l.decodePathIdentifier(data, RF_IPv6_MPLS, options) + if err != nil { + return err + } + if len(data) < 1 { + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") + } + l.Length = uint8(data[0]) + data = data[1:] + err = l.Labels.DecodeFromBytes(data) + if err != nil { + return err + } + data = data[l.Labels.Len():] + l.decodePrefix(data, l.PrefixLen()) + return nil +} + +func (l *LabeledIPv6AddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { + buf, err := l.serializeIdentifier(RF_IPv6_MPLS, options) + if err != nil { + return nil, err + } + buf = append(buf, l.Length) + lBuf, err := l.Labels.Serialize() + if err != nil { + return nil, err + } + buf = append(buf, lBuf...) + pBuf, err := l.serializePrefix(l.PrefixLen()) + if err != nil { + return nil, err + } + return append(buf, pBuf...), nil +} + +func (l *LabeledIPv6AddrPrefix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + Labels []uint32 `json:"labels"` + }{ + Prefix: l.String(), + Labels: l.Labels.Labels, + }) } -func NewLabeledIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPv6AddrPrefix { +func NewLabeledIPv6AddrPrefix(length uint8, prefix string, labels MPLSLabelStack) *LabeledIPv6AddrPrefix { return &LabeledIPv6AddrPrefix{ - LabeledIPAddrPrefix{ - IPAddrPrefixDefault{ - Length: length + uint8(label.Len()*8), - Prefix: net.ParseIP(prefix), - }, - label, - 16, + ipv6AddrPrefix: ipv6AddrPrefix{ + Length: length + uint8(labels.Len()*8), + Prefix: net.ParseIP(prefix).To16(), + }, + labeledPrefix: labeledPrefix{ + Labels: labels, }, } } @@ -1841,26 +1970,23 @@ type RouteTargetMembershipNLRI struct { } func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - if IsAddPathEnabled(true, RF_RTC_UC, options) { - var err error - data, err = n.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := n.decodePathIdentifier(data, RF_RTC_UC, options) + if err != nil { + return err } if len(data) < 1 { return NewMessageError(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), nil, "prefix misses length field") } n.Length = data[0] data = data[1:] - if len(data) == 0 { + if n.Length == 0 { return nil - } else if len(data) != 12 { - return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all RouteTargetMembershipNLRI bytes available") + } + if len(data) != 12 { + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Invalid RouteTargetMembershipNLRI byte length") } n.AS = binary.BigEndian.Uint32(data[0:4]) - rt, err := ParseExtended(data[4:]) - n.RouteTarget = rt + n.RouteTarget, err = ParseExtended(data[4:]) if err != nil { return err } @@ -1868,26 +1994,23 @@ func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*Mar } func (n *RouteTargetMembershipNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { - var buf []byte - if IsAddPathEnabled(false, RF_RTC_UC, options) { - var err error - buf, err = n.serializeIdentifier() - if err != nil { - return nil, err - } + buf, err := n.serializeIdentifier(RF_RTC_UC, options) + if err != nil { + return nil, err } if n.RouteTarget == nil { return append(buf, 0), nil } - offset := len(buf) - buf = append(buf, make([]byte, 5)...) - buf[offset] = 12 * 8 - binary.BigEndian.PutUint32(buf[offset+1:], n.AS) - ebuf, err := n.RouteTarget.Serialize() + n.Length = 96 // 12*8 + buf = append(buf, n.Length) + asBuf := make([]byte, 4) + binary.BigEndian.PutUint32(asBuf, n.AS) + buf = append(buf, asBuf...) + rtBuf, err := n.RouteTarget.Serialize() if err != nil { return nil, err } - return append(buf, ebuf...), nil + return append(buf, rtBuf...), nil } func (n *RouteTargetMembershipNLRI) AFI() uint16 { @@ -1922,7 +2045,7 @@ func (n *RouteTargetMembershipNLRI) MarshalJSON() ([]byte, error) { } func NewRouteTargetMembershipNLRI(as uint32, target ExtendedCommunityInterface) *RouteTargetMembershipNLRI { - l := 12 * 8 + l := 96 // 12*8 if as == 0 && target == nil { l = 1 } @@ -2017,7 +2140,8 @@ func (esi *EthernetSegmentIdentifier) String() string { return s.String() } -// Decode Ethernet Segment Identifier (ESI) from string slice. +// ParseEthernetSegmentIdentifier decodes Ethernet Segment Identifier (ESI) +// from string slice. // // The first element of args should be the Type field (e.g., "ARBITRARY", // "arbitrary", "ESI_ARBITRARY" or "esi_arbitrary") and "single-homed" is @@ -2709,12 +2833,9 @@ type EVPNNLRI struct { } func (n *EVPNNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - if IsAddPathEnabled(true, RF_EVPN, options) { - var err error - data, err = n.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := n.decodePathIdentifier(data, RF_EVPN, options) + if err != nil { + return err } if len(data) < 2 { return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPNNLRI bytes available") @@ -2725,33 +2846,25 @@ func (n *EVPNNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) e if len(data) < int(n.Length) { return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPNNLRI Route type bytes available") } - r, err := getEVPNRouteType(n.RouteType) + n.RouteTypeData, err = getEVPNRouteType(n.RouteType) if err != nil { return err } - n.RouteTypeData = r return n.RouteTypeData.DecodeFromBytes(data[:n.Length]) } func (n *EVPNNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { - var buf []byte - if IsAddPathEnabled(false, RF_EVPN, options) { - var err error - buf, err = n.serializeIdentifier() - if err != nil { - return nil, err - } + buf, err := n.serializeIdentifier(RF_EVPN, options) + if err != nil { + return nil, err } - offset := len(buf) - buf = append(buf, make([]byte, 2)...) - buf[offset] = n.RouteType - tbuf, err := n.RouteTypeData.Serialize() - n.Length = uint8(len(tbuf)) - buf[offset+1] = n.Length + tBuf, err := n.RouteTypeData.Serialize() if err != nil { return nil, err } - return append(buf, tbuf...), nil + n.Length = uint8(len(tBuf)) + buf = append(buf, n.RouteType, n.Length) + return append(buf, tBuf...), nil } func (n *EVPNNLRI) AFI() uint16 { @@ -2795,97 +2908,127 @@ func NewEVPNNLRI(routetype uint8, length uint8, routetypedata EVPNRouteTypeInter } } +type encapNLRI struct { + Length uint8 + Prefix net.IP +} + +func (n *encapNLRI) SAFI() uint8 { + return SAFI_ENCAPSULATION +} + +func (n *encapNLRI) String() string { + return n.Prefix.String() +} + +func (n *encapNLRI) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Prefix string `json:"prefix"` + }{ + Prefix: n.Prefix.String(), + }) +} + type EncapNLRI struct { - IPAddrPrefixDefault - addrlen uint8 + PrefixDefault + encapNLRI } func (n *EncapNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { - if n.addrlen == 0 { - n.addrlen = 4 - } - f := RF_IPv4_ENCAP - if n.addrlen == 16 { - f = RF_IPv6_ENCAP - } - if IsAddPathEnabled(true, f, options) { - var err error - data, err = n.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := n.decodePathIdentifier(data, RF_IPv4_ENCAP, options) + if err != nil { + return err } - if len(data) < 4 { + if len(data) != 5 { eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) - return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") + return NewMessageError(eCode, eSubCode, nil, "invalid ipv4 encapsulation nlri byte length") } n.Length = data[0] - if n.addrlen == 0 { - n.addrlen = 4 - } - return n.decodePrefix(data[1:], n.Length, n.addrlen) + n.Prefix = data[1:5] + return nil } func (n *EncapNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { - var buf []byte - f := RF_IPv4_ENCAP - if n.addrlen == 16 { - f = RF_IPv6_ENCAP - } - if IsAddPathEnabled(false, f, options) { - var err error - buf, err = n.serializeIdentifier() - if err != nil { - return nil, err - } - } - if n.Prefix.To4() != nil { - buf = append(buf, net.IPv4len*8) - n.Prefix = n.Prefix.To4() - } else { - buf = append(buf, net.IPv6len*8) - } - n.Length = buf[len(buf)-1] - pbuf, err := n.serializePrefix(n.Length) + buf, err := n.serializeIdentifier(RF_IPv4_ENCAP, options) if err != nil { return nil, err } - return append(buf, pbuf...), nil -} - -func (n *EncapNLRI) String() string { - return n.Prefix.String() + prefix := n.Prefix.To4() + if prefix == nil { + return nil, fmt.Errorf("invalid address for ipv4 encapsulation nlri: %s", n.Prefix.String()) + } + n.Prefix = prefix + n.Length = 32 + buf = append(buf, n.Length) + return append(buf, n.Prefix...), nil } func (n *EncapNLRI) AFI() uint16 { return AFI_IP } -func (n *EncapNLRI) SAFI() uint8 { - return SAFI_ENCAPSULATION +func (n *EncapNLRI) Len(options ...*MarshallingOption) int { + return 5 } func NewEncapNLRI(endpoint string) *EncapNLRI { return &EncapNLRI{ - IPAddrPrefixDefault{Length: 32, Prefix: net.ParseIP(endpoint).To4()}, - 4, + encapNLRI: encapNLRI{ + Length: 32, + Prefix: net.ParseIP(endpoint).To4(), + }, } } type Encapv6NLRI struct { - EncapNLRI + PrefixDefault + encapNLRI +} + +func (n *Encapv6NLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { + data, err := n.decodePathIdentifier(data, RF_IPv6_ENCAP, options) + if err != nil { + return err + } + if len(data) != 17 { + eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) + eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) + return NewMessageError(eCode, eSubCode, nil, "invalid ipv6 encapsulation nlri byte length") + } + n.Length = data[0] + n.Prefix = data[1:17] + return nil +} + +func (n *Encapv6NLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { + buf, err := n.serializeIdentifier(RF_IPv6_ENCAP, options) + if err != nil { + return nil, err + } + prefix := n.Prefix.To16() + if prefix == nil { + return nil, fmt.Errorf("invalid address for ipv6 encapsulation nlri: %s", n.Prefix.String()) + } + n.Prefix = prefix + n.Length = 128 + buf = append(buf, n.Length) + return append(buf, n.Prefix...), nil } func (n *Encapv6NLRI) AFI() uint16 { return AFI_IP6 } +func (n *Encapv6NLRI) Len(options ...*MarshallingOption) int { + return 17 +} + func NewEncapv6NLRI(endpoint string) *Encapv6NLRI { return &Encapv6NLRI{ - EncapNLRI{ - IPAddrPrefixDefault{Length: 128, Prefix: net.ParseIP(endpoint)}, - 16, + encapNLRI: encapNLRI{ + Length: 128, + Prefix: net.ParseIP(endpoint), }, } } @@ -3160,9 +3303,9 @@ func flowSpecPrefixParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (F } switch typ { case FLOW_SPEC_TYPE_DST_PREFIX: - return NewFlowSpecDestinationPrefix(NewIPAddrPrefix(uint8(prefixLen), prefix.String())), nil + return NewFlowSpecDestinationPrefix(uint8(prefixLen), prefix.String()), nil case FLOW_SPEC_TYPE_SRC_PREFIX: - return NewFlowSpecSourcePrefix(NewIPAddrPrefix(uint8(prefixLen), prefix.String())), nil + return NewFlowSpecSourcePrefix(uint8(prefixLen), prefix.String()), nil } return nil, fmt.Errorf("invalid traffic filtering rule type: %s", typ.String()) case AFI_IP6: @@ -3212,16 +3355,16 @@ func flowSpecPrefixParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (F } switch typ { case FLOW_SPEC_TYPE_DST_PREFIX: - return NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(uint8(prefixLen), prefix.String()), uint8(offset)), nil + return NewFlowSpecDestinationPrefix6(uint8(prefixLen), uint8(offset), prefix.String()), nil case FLOW_SPEC_TYPE_SRC_PREFIX: - return NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(uint8(prefixLen), prefix.String()), uint8(offset)), nil + return NewFlowSpecSourcePrefix6(uint8(prefixLen), uint8(offset), prefix.String()), nil } return nil, fmt.Errorf("invalid traffic filtering rule type: %s", typ.String()) } return nil, fmt.Errorf("invalid address family: %s", rf.String()) } -func flowSpecIpProtoParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { +func flowSpecIPProtoParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { // args: List of pairs of Operator and IP protocol type // // Example: @@ -3246,7 +3389,7 @@ func flowSpecIpProtoParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (F return parseFlowSpecNumericOpValues(typ, args, f) } -func flowSpecTcpFlagParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { +func flowSpecTCPFlagParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { // args: List of pairs of Operand and TCP Flags // // Example: @@ -3486,13 +3629,13 @@ func flowSpecVlanCosParser(rf RouteFamily, typ BGPFlowSpecType, args []string) ( var flowSpecParserMap = map[BGPFlowSpecType]func(RouteFamily, BGPFlowSpecType, []string) (FlowSpecComponentInterface, error){ FLOW_SPEC_TYPE_DST_PREFIX: flowSpecPrefixParser, FLOW_SPEC_TYPE_SRC_PREFIX: flowSpecPrefixParser, - FLOW_SPEC_TYPE_IP_PROTO: flowSpecIpProtoParser, + FLOW_SPEC_TYPE_IP_PROTO: flowSpecIPProtoParser, FLOW_SPEC_TYPE_PORT: flowSpecNumeric2BytesParser, FLOW_SPEC_TYPE_DST_PORT: flowSpecNumeric2BytesParser, FLOW_SPEC_TYPE_SRC_PORT: flowSpecNumeric2BytesParser, FLOW_SPEC_TYPE_ICMP_TYPE: flowSpecNumeric1ByteParser, FLOW_SPEC_TYPE_ICMP_CODE: flowSpecNumeric1ByteParser, - FLOW_SPEC_TYPE_TCP_FLAG: flowSpecTcpFlagParser, + FLOW_SPEC_TYPE_TCP_FLAG: flowSpecTCPFlagParser, FLOW_SPEC_TYPE_PKT_LEN: flowSpecNumeric2BytesParser, FLOW_SPEC_TYPE_DSCP: flowSpecDscpParser, FLOW_SPEC_TYPE_FRAGMENT: flowSpecFragmentParser, @@ -3568,28 +3711,38 @@ type FlowSpecComponentInterface interface { String() string } +// RFC5575 +// Encoding: type flowSpecPrefix struct { - Prefix AddrPrefixInterface + Length uint8 + Prefix net.IP typ BGPFlowSpecType } -func (p *flowSpecPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { +func (p *flowSpecPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) (err error) { + if len(data) < 2 { + return fmt.Errorf("not enough byte length for flowSpecPrefix: %d", len(data)) + } p.typ = BGPFlowSpecType(data[0]) - return p.Prefix.DecodeFromBytes(data[1:], options...) + p.Length = data[1] + p.Prefix, err = decodeIPAddrPrefix(data[2:], p.Length, net.IPv4len) + return err } -func (p *flowSpecPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { - buf := []byte{byte(p.Type())} - bbuf, err := p.Prefix.Serialize(options...) +func (p *flowSpecPrefix) Serialize(options ...*MarshallingOption) (buf []byte, err error) { + buf = make([]byte, 2) + buf[0] = byte(p.Type()) + buf[1] = p.Length + var pBuf []byte + p.Prefix, pBuf, err = serializeIPAddrPrefix(p.Prefix, p.Length) if err != nil { return nil, err } - return append(buf, bbuf...), nil + return append(buf, pBuf...), nil } func (p *flowSpecPrefix) Len(options ...*MarshallingOption) int { - buf, _ := p.Serialize(options...) - return len(buf) + return 2 + (int(p.Length)+7)/8 } func (p *flowSpecPrefix) Type() BGPFlowSpecType { @@ -3597,48 +3750,54 @@ func (p *flowSpecPrefix) Type() BGPFlowSpecType { } func (p *flowSpecPrefix) String() string { - return fmt.Sprintf("[%s: %s]", p.Type(), p.Prefix.String()) + return fmt.Sprintf("[%s: %s/%d]", p.Type(), p.Prefix.String(), p.Length) } func (p *flowSpecPrefix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Type BGPFlowSpecType `json:"type"` - Value AddrPrefixInterface `json:"value"` + Type BGPFlowSpecType `json:"type"` + Value string `json:"value"` }{ Type: p.Type(), - Value: p.Prefix, + Value: fmt.Sprintf("%s/%d", p.Prefix.String(), p.Length), }) } +// draft-ietf-idr-flow-spec-v6-09 +// Encoding: type flowSpecPrefix6 struct { - Prefix AddrPrefixInterface + Length uint8 Offset uint8 + Prefix net.IP typ BGPFlowSpecType } -// draft-ietf-idr-flow-spec-v6-06 -// -func (p *flowSpecPrefix6) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { +func (p *flowSpecPrefix6) DecodeFromBytes(data []byte, options ...*MarshallingOption) (err error) { + if len(data) < 3 { + return fmt.Errorf("not enough byte length for flowSpecPrefix6: %d", len(data)) + } p.typ = BGPFlowSpecType(data[0]) + p.Length = data[1] p.Offset = data[2] - prefix := append([]byte{data[1]}, data[3:]...) - return p.Prefix.DecodeFromBytes(prefix, options...) + p.Prefix, err = decodeIPAddrPrefix(data[3:], p.Length, net.IPv6len) + return err } -func (p *flowSpecPrefix6) Serialize(options ...*MarshallingOption) ([]byte, error) { - buf := []byte{byte(p.Type())} - bbuf, err := p.Prefix.Serialize(options...) +func (p *flowSpecPrefix6) Serialize(options ...*MarshallingOption) (buf []byte, err error) { + buf = make([]byte, 3) + buf[0] = byte(p.Type()) + buf[1] = p.Length + buf[2] = p.Offset + var pBuf []byte + p.Prefix, pBuf, err = serializeIPAddrPrefix(p.Prefix, p.Length) if err != nil { return nil, err } - buf = append(buf, bbuf[0]) - buf = append(buf, p.Offset) - return append(buf, bbuf[1:]...), nil + return append(buf, pBuf...), nil } func (p *flowSpecPrefix6) Len(options ...*MarshallingOption) int { - buf, _ := p.Serialize(options...) - return len(buf) + return 3 + (int(p.Length)+7)/8 } func (p *flowSpecPrefix6) Type() BGPFlowSpecType { @@ -3646,17 +3805,17 @@ func (p *flowSpecPrefix6) Type() BGPFlowSpecType { } func (p *flowSpecPrefix6) String() string { - return fmt.Sprintf("[%s: %s/%d]", p.Type(), p.Prefix.String(), p.Offset) + return fmt.Sprintf("[%s: %s/%d/%d]", p.Type(), p.Prefix.String(), p.Length, p.Offset) } func (p *flowSpecPrefix6) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Type BGPFlowSpecType `json:"type"` - Value AddrPrefixInterface `json:"value"` - Offset uint8 `json:"offset"` + Type BGPFlowSpecType `json:"type"` + Value string `json:"value"` + Offset uint8 `json:"offset"` }{ Type: p.Type(), - Value: p.Prefix, + Value: fmt.Sprintf("%s/%d", p.Prefix.String(), p.Length), Offset: p.Offset, }) } @@ -3665,32 +3824,58 @@ type FlowSpecDestinationPrefix struct { flowSpecPrefix } -func NewFlowSpecDestinationPrefix(prefix AddrPrefixInterface) *FlowSpecDestinationPrefix { - return &FlowSpecDestinationPrefix{flowSpecPrefix{prefix, FLOW_SPEC_TYPE_DST_PREFIX}} +func NewFlowSpecDestinationPrefix(length uint8, prefix string) *FlowSpecDestinationPrefix { + return &FlowSpecDestinationPrefix{ + flowSpecPrefix: flowSpecPrefix{ + Length: length, + Prefix: net.ParseIP(prefix).To4(), + typ: FLOW_SPEC_TYPE_DST_PREFIX, + }, + } } type FlowSpecSourcePrefix struct { flowSpecPrefix } -func NewFlowSpecSourcePrefix(prefix AddrPrefixInterface) *FlowSpecSourcePrefix { - return &FlowSpecSourcePrefix{flowSpecPrefix{prefix, FLOW_SPEC_TYPE_SRC_PREFIX}} +func NewFlowSpecSourcePrefix(length uint8, prefix string) *FlowSpecSourcePrefix { + return &FlowSpecSourcePrefix{ + flowSpecPrefix: flowSpecPrefix{ + Length: length, + Prefix: net.ParseIP(prefix).To4(), + typ: FLOW_SPEC_TYPE_SRC_PREFIX, + }, + } } type FlowSpecDestinationPrefix6 struct { flowSpecPrefix6 } -func NewFlowSpecDestinationPrefix6(prefix AddrPrefixInterface, offset uint8) *FlowSpecDestinationPrefix6 { - return &FlowSpecDestinationPrefix6{flowSpecPrefix6{prefix, offset, FLOW_SPEC_TYPE_DST_PREFIX}} +func NewFlowSpecDestinationPrefix6(length uint8, offset uint8, prefix string) *FlowSpecDestinationPrefix6 { + return &FlowSpecDestinationPrefix6{ + flowSpecPrefix6: flowSpecPrefix6{ + Length: length, + Offset: offset, + Prefix: net.ParseIP(prefix).To16(), + typ: FLOW_SPEC_TYPE_DST_PREFIX, + }, + } } type FlowSpecSourcePrefix6 struct { flowSpecPrefix6 } -func NewFlowSpecSourcePrefix6(prefix AddrPrefixInterface, offset uint8) *FlowSpecSourcePrefix6 { - return &FlowSpecSourcePrefix6{flowSpecPrefix6{prefix, offset, FLOW_SPEC_TYPE_SRC_PREFIX}} +func NewFlowSpecSourcePrefix6(length uint8, offset uint8, prefix string) *FlowSpecSourcePrefix6 { + return &FlowSpecSourcePrefix6{ + flowSpecPrefix6{ + Length: length, + Offset: offset, + Prefix: net.ParseIP(prefix).To16(), + typ: FLOW_SPEC_TYPE_SRC_PREFIX, + }, + } } type flowSpecMac struct { @@ -4026,12 +4211,9 @@ func (n *FlowSpecNLRI) RD() RouteDistinguisherInterface { } func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*MarshallingOption) error { - if IsAddPathEnabled(true, rf, options) { - var err error - data, err = n.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := n.decodePathIdentifier(data, rf, options) + if err != nil { + return err } var length int if (data[0]>>4) == 0xf && len(data) > 2 { @@ -4065,18 +4247,18 @@ func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...* case FLOW_SPEC_TYPE_DST_PREFIX: switch { case rf>>16 == AFI_IP: - i = NewFlowSpecDestinationPrefix(NewIPAddrPrefix(0, "")) + i = NewFlowSpecDestinationPrefix(0, "") case rf>>16 == AFI_IP6: - i = NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(0, ""), 0) + i = NewFlowSpecDestinationPrefix6(0, 0, "") default: return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) } case FLOW_SPEC_TYPE_SRC_PREFIX: switch { case rf>>16 == AFI_IP: - i = NewFlowSpecSourcePrefix(NewIPAddrPrefix(0, "")) + i = NewFlowSpecSourcePrefix(0, "") case rf>>16 == AFI_IP6: - i = NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(0, ""), 0) + i = NewFlowSpecSourcePrefix6(0, 0, "") default: return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) } @@ -4143,7 +4325,7 @@ func (n *FlowSpecNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) if length > 0xfff { return nil, fmt.Errorf("Too large: %d", length) } else if length < 0xf0 { - length -= 1 + length-- buf = append([]byte{byte(length)}, buf...) } else { length -= 2 @@ -4152,14 +4334,11 @@ func (n *FlowSpecNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) buf = append(b, buf...) } - if IsAddPathEnabled(false, n.rf, options) { - id, err := n.serializeIdentifier() - if err != nil { - return nil, err - } - return append(id, buf...), nil + id, err := n.serializeIdentifier(n.rf, options) + if err != nil { + return nil, err } - return buf, nil + return append(id, buf...), nil } func (n *FlowSpecNLRI) Len(options ...*MarshallingOption) int { @@ -4172,9 +4351,8 @@ func (n *FlowSpecNLRI) Len(options ...*MarshallingOption) int { } if l < 0xf0 { return l + 1 - } else { - return l + 2 } + return l + 2 } func (n *FlowSpecNLRI) String() string { @@ -4206,12 +4384,10 @@ func (n *FlowSpecNLRI) MarshalJSON() ([]byte, error) { } -// -// CompareFlowSpecNLRI(n, m) returns +// CompareFlowSpecNLRI returns // -1 when m has precedence // 0 when n and m have same precedence // 1 when n has precedence -// func CompareFlowSpecNLRI(n, m *FlowSpecNLRI) (int, error) { family := AfiSafiToRouteFamily(n.AFI(), n.SAFI()) if family != AfiSafiToRouteFamily(m.AFI(), m.SAFI()) { @@ -4247,44 +4423,54 @@ func CompareFlowSpecNLRI(n, m *FlowSpecNLRI) (int, error) { // For IP prefix values (IP destination and source prefix) precedence is // given to the lowest IP value of the common prefix length; if the // common prefix is equal, then the most specific prefix has precedence. - var p, q *IPAddrPrefixDefault + var pLength, qLength uint8 var pCommon, qCommon uint64 if n.AFI() == AFI_IP { + var pPrefix, qPrefix net.IP if v.Type() == FLOW_SPEC_TYPE_DST_PREFIX { - p = &v.(*FlowSpecDestinationPrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault - q = &w.(*FlowSpecDestinationPrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault + pLength = v.(*FlowSpecDestinationPrefix).Length + pPrefix = v.(*FlowSpecDestinationPrefix).Prefix + qLength = w.(*FlowSpecDestinationPrefix).Length + qPrefix = w.(*FlowSpecDestinationPrefix).Prefix } else { - p = &v.(*FlowSpecSourcePrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault - q = &w.(*FlowSpecSourcePrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault + pLength = v.(*FlowSpecSourcePrefix).Length + pPrefix = v.(*FlowSpecSourcePrefix).Prefix + qLength = w.(*FlowSpecSourcePrefix).Length + qPrefix = w.(*FlowSpecSourcePrefix).Prefix } - min := p.Length - if q.Length < p.Length { - min = q.Length + min := pLength + if qLength < pLength { + min = qLength } - pCommon = uint64(binary.BigEndian.Uint32([]byte(p.Prefix.To4())) >> (32 - min)) - qCommon = uint64(binary.BigEndian.Uint32([]byte(q.Prefix.To4())) >> (32 - min)) + pCommon = uint64(binary.BigEndian.Uint32([]byte(pPrefix.To4())) >> (32 - min)) + qCommon = uint64(binary.BigEndian.Uint32([]byte(qPrefix.To4())) >> (32 - min)) } else if n.AFI() == AFI_IP6 { + var pPrefix, qPrefix net.IP if v.Type() == FLOW_SPEC_TYPE_DST_PREFIX { - p = &v.(*FlowSpecDestinationPrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault - q = &w.(*FlowSpecDestinationPrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault + pLength = v.(*FlowSpecDestinationPrefix6).Length + pPrefix = v.(*FlowSpecDestinationPrefix6).Prefix + qLength = w.(*FlowSpecDestinationPrefix6).Length + qPrefix = w.(*FlowSpecDestinationPrefix6).Prefix } else { - p = &v.(*FlowSpecSourcePrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault - q = &w.(*FlowSpecSourcePrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault + pLength = v.(*FlowSpecDestinationPrefix6).Length + pPrefix = v.(*FlowSpecDestinationPrefix6).Prefix + qLength = w.(*FlowSpecDestinationPrefix6).Length + qPrefix = w.(*FlowSpecDestinationPrefix6).Prefix } - min := uint(p.Length) - if q.Length < p.Length { - min = uint(q.Length) + min := pLength + if qLength < pLength { + min = qLength } - var mask uint + var mask uint8 if min-64 > 0 { mask = min - 64 } - pCommon = binary.BigEndian.Uint64([]byte(p.Prefix.To16()[:8])) >> mask - qCommon = binary.BigEndian.Uint64([]byte(q.Prefix.To16()[:8])) >> mask + pCommon = binary.BigEndian.Uint64([]byte(pPrefix.To16()[:8])) >> mask + qCommon = binary.BigEndian.Uint64([]byte(qPrefix.To16()[:8])) >> mask if pCommon == qCommon && mask == 0 { mask = 64 - min - pCommon = binary.BigEndian.Uint64([]byte(p.Prefix.To16()[8:])) >> mask - qCommon = binary.BigEndian.Uint64([]byte(q.Prefix.To16()[8:])) >> mask + pCommon = binary.BigEndian.Uint64([]byte(pPrefix.To16()[8:])) >> mask + qCommon = binary.BigEndian.Uint64([]byte(qPrefix.To16()[8:])) >> mask } } @@ -4292,9 +4478,9 @@ func CompareFlowSpecNLRI(n, m *FlowSpecNLRI) (int, error) { return invert, nil } else if pCommon > qCommon { return invert * -1, nil - } else if p.Length > q.Length { + } else if pLength > qLength { return invert, nil - } else if p.Length < q.Length { + } else if pLength < qLength { return invert * -1, nil } @@ -4431,12 +4617,9 @@ func (n *OpaqueNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) if len(data) < 2 { return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all OpaqueNLRI bytes available") } - if IsAddPathEnabled(true, RF_OPAQUE, options) { - var err error - data, err = n.decodePathIdentifier(data) - if err != nil { - return err - } + data, err := n.decodePathIdentifier(data, RF_OPAQUE, options) + if err != nil { + return err } n.Length = binary.BigEndian.Uint16(data[0:2]) if len(data)-2 < int(n.Length) { @@ -4455,14 +4638,11 @@ func (n *OpaqueNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { binary.BigEndian.PutUint16(buf, uint16(len(n.Key))) buf = append(buf, n.Key...) buf = append(buf, n.Value...) - if IsAddPathEnabled(false, RF_OPAQUE, options) { - id, err := n.serializeIdentifier() - if err != nil { - return nil, err - } - return append(id, buf...), nil + id, err := n.serializeIdentifier(RF_OPAQUE, options) + if err != nil { + return nil, err } - return buf, nil + return append(id, buf...), nil } func (n *OpaqueNLRI) AFI() uint16 { @@ -4863,7 +5043,7 @@ func NewNotificationErrorCode(code, subcode uint8) NotificationErrorCode { return NotificationErrorCode(uint16(code)<<8 | uint16(subcode)) } -var PathAttrFlags map[BGPAttrType]BGPAttrFlag = map[BGPAttrType]BGPAttrFlag{ +var PathAttrFlags = map[BGPAttrType]BGPAttrFlag{ BGP_ATTR_TYPE_ORIGIN: BGP_ATTR_FLAG_TRANSITIVE, BGP_ATTR_TYPE_AS_PATH: BGP_ATTR_FLAG_TRANSITIVE, BGP_ATTR_TYPE_NEXT_HOP: BGP_ATTR_FLAG_TRANSITIVE, @@ -7786,35 +7966,35 @@ func (t *TunnelEncapTLV) DecodeFromBytes(data []byte) error { return nil } -func (p *TunnelEncapTLV) Serialize() ([]byte, error) { +func (t *TunnelEncapTLV) Serialize() ([]byte, error) { buf := make([]byte, 4) - for _, t := range p.Value { - tBuf, err := t.Serialize() + for _, tlv := range t.Value { + tBuf, err := tlv.Serialize() if err != nil { return nil, err } buf = append(buf, tBuf...) } - binary.BigEndian.PutUint16(buf, uint16(p.Type)) + binary.BigEndian.PutUint16(buf, uint16(t.Type)) binary.BigEndian.PutUint16(buf[2:], uint16(len(buf)-4)) return buf, nil } -func (p *TunnelEncapTLV) String() string { - tlvList := make([]string, len(p.Value), len(p.Value)) - for i, v := range p.Value { +func (t *TunnelEncapTLV) String() string { + tlvList := make([]string, len(t.Value), len(t.Value)) + for i, v := range t.Value { tlvList[i] = v.String() } - return fmt.Sprintf("{%s: %s}", p.Type, strings.Join(tlvList, ", ")) + return fmt.Sprintf("{%s: %s}", t.Type, strings.Join(tlvList, ", ")) } -func (p *TunnelEncapTLV) MarshalJSON() ([]byte, error) { +func (t *TunnelEncapTLV) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Type TunnelType `json:"type"` Value []TunnelEncapSubTLVInterface `json:"value"` }{ - Type: p.Type, - Value: p.Value, + Type: t.Type, + Value: t.Value, }) } @@ -8739,19 +8919,18 @@ func NewBGPUpdateMessage(withdrawnRoutes []*IPAddrPrefix, pathattrs []PathAttrib func NewEndOfRib(family RouteFamily) *BGPMessage { if family == RF_IPv4_UC { return NewBGPUpdateMessage(nil, nil, nil) - } else { - afi, safi := RouteFamilyToAfiSafi(family) - t := BGP_ATTR_TYPE_MP_UNREACH_NLRI - unreach := &PathAttributeMpUnreachNLRI{ - PathAttribute: PathAttribute{ - Flags: PathAttrFlags[t], - Type: t, - }, - AFI: afi, - SAFI: safi, - } - return NewBGPUpdateMessage(nil, []PathAttributeInterface{unreach}, nil) } + afi, safi := RouteFamilyToAfiSafi(family) + t := BGP_ATTR_TYPE_MP_UNREACH_NLRI + unreach := &PathAttributeMpUnreachNLRI{ + PathAttribute: PathAttribute{ + Flags: PathAttrFlags[t], + Type: t, + }, + AFI: afi, + SAFI: safi, + } + return NewBGPUpdateMessage(nil, []PathAttributeInterface{unreach}, nil) } type BGPNotification struct { @@ -9133,55 +9312,70 @@ func (p *PathAttribute) Flat() map[string]string { } func (l *LabeledVPNIPAddrPrefix) Flat() map[string]string { - prefixLen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) + prefixLen := l.ipAddrPrefix.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) return map[string]string{ - "Prefix": l.IPAddrPrefixDefault.Prefix.String(), + "Prefix": l.ipAddrPrefix.Prefix.String(), "PrefixLen": fmt.Sprintf("%d", prefixLen), "NLRI": l.String(), "Label": l.Labels.String(), } } -func (p *IPAddrPrefixDefault) Flat() map[string]string { - l := strings.Split(p.String(), "/") - if len(l) == 2 { - return map[string]string{ - "Prefix": l[0], - "PrefixLen": l[1], - } +func (r *ipAddrPrefix) Flat() map[string]string { + return map[string]string{ + "Prefix": r.Prefix.String(), + "PrefixLen": fmt.Sprint(r.Length), + } +} + +func (r *ipv6AddrPrefix) Flat() map[string]string { + return map[string]string{ + "Prefix": r.Prefix.String(), + "PrefixLen": fmt.Sprint(r.Length), + } +} + +func (n *encapNLRI) Flat() map[string]string { + return map[string]string{ + "Prefix": n.Prefix.String(), } - return map[string]string{} } -func (l *EVPNNLRI) Flat() map[string]string { +func (n *EVPNNLRI) Flat() map[string]string { return map[string]string{} } -func (l *RouteTargetMembershipNLRI) Flat() map[string]string { + +func (n *RouteTargetMembershipNLRI) Flat() map[string]string { return map[string]string{} } -func (l *FlowSpecIPv4Unicast) Flat() map[string]string { + +func (n *FlowSpecIPv4Unicast) Flat() map[string]string { return map[string]string{} } -func (l *FlowSpecIPv4VPN) Flat() map[string]string { + +func (n *FlowSpecIPv4VPN) Flat() map[string]string { return map[string]string{} } -func (l *FlowSpecIPv6Unicast) Flat() map[string]string { + +func (n *FlowSpecIPv6Unicast) Flat() map[string]string { return map[string]string{} } -func (l *FlowSpecIPv6VPN) Flat() map[string]string { + +func (n *FlowSpecIPv6VPN) Flat() map[string]string { return map[string]string{} } -func (l *FlowSpecL2VPN) Flat() map[string]string { + +func (n *FlowSpecL2VPN) Flat() map[string]string { return map[string]string{} } -func (l *OpaqueNLRI) Flat() map[string]string { + +func (n *OpaqueNLRI) Flat() map[string]string { return map[string]string{} } -// Update a Flat representation by adding elements of the second -// one. If two elements use same keys, values are separated with -// ';'. In this case, it returns an error but the update has been -// realized. +// FlatUpdate updates a Flat representation by adding elements of the second +// one. If two elements use same keys, values are separated with ';'. In this +// case, it returns an error but the update has been realized. func FlatUpdate(f1, f2 map[string]string) error { conflict := false for k2, v2 := range f2 { @@ -9194,7 +9388,6 @@ func FlatUpdate(f1, f2 map[string]string) error { } if conflict { return fmt.Errorf("Keys conflict") - } else { - return nil } + return nil } diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go index 1b9df371b..e1f7e637f 100644 --- a/packet/bgp/bgp_test.go +++ b/packet/bgp/bgp_test.go @@ -91,6 +91,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // IPv4AddressSpecificExtended buf = make([]byte, 13) + buf[0] = 12 binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_IP4_SPECIFIC) // typehigh ip := net.ParseIP("10.0.0.1").To4() @@ -108,6 +109,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // FourOctetAsSpecificExtended buf = make([]byte, 13) + buf[0] = 12 binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) // typehigh buf[6] = byte(EC_SUBTYPE_ROUTE_TARGET) // subtype @@ -125,6 +127,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // OpaqueExtended buf = make([]byte, 13) + buf[0] = 12 binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_OPAQUE) // typehigh binary.BigEndian.PutUint32(buf[9:], 1000000) @@ -140,6 +143,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // Unknown buf = make([]byte, 13) + buf[0] = 12 binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = 0x04 // typehigh binary.BigEndian.PutUint32(buf[9:], 1000000) @@ -356,8 +360,8 @@ func Test_MPLSLabelStack(t *testing.T) { func Test_FlowSpecNlri(t *testing.T) { assert := assert.New(t) cmp := make([]FlowSpecComponentInterface, 0) - cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) - cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) + cmp = append(cmp, NewFlowSpecDestinationPrefix(24, "10.0.0.0")) + cmp = append(cmp, NewFlowSpecSourcePrefix(24, "10.0.0.0")) item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20) @@ -444,8 +448,8 @@ func Test_IP6FlowSpecExtended(t *testing.T) { func Test_FlowSpecNlriv6(t *testing.T) { assert := assert.New(t) cmp := make([]FlowSpecComponentInterface, 0) - cmp = append(cmp, NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(64, "2001::"), 12)) - cmp = append(cmp, NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(64, "2001::"), 12)) + cmp = append(cmp, NewFlowSpecDestinationPrefix6(64, 12, "2001::")) + cmp = append(cmp, NewFlowSpecSourcePrefix6(64, 12, "2001::")) item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20) @@ -542,8 +546,8 @@ func Test_NotificationErrorCode(t *testing.T) { func Test_FlowSpecNlriVPN(t *testing.T) { assert := assert.New(t) cmp := make([]FlowSpecComponentInterface, 0) - cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) - cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) + cmp = append(cmp, NewFlowSpecDestinationPrefix(24, "10.0.0.0")) + cmp = append(cmp, NewFlowSpecSourcePrefix(24, "10.0.0.0")) rd, _ := ParseRouteDistinguisher("100:100") n1 := NewFlowSpecIPv4VPN(rd, cmp) buf1, err := n1.Serialize() @@ -739,7 +743,7 @@ func Test_AddPath(t *testing.T) { } opt = &MarshallingOption{AddPath: map[RouteFamily]BGPAddPathMode{RF_FS_IPv4_UC: BGP_ADD_PATH_BOTH}} { - n1 := NewFlowSpecIPv4Unicast([]FlowSpecComponentInterface{NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))}) + n1 := NewFlowSpecIPv4Unicast([]FlowSpecComponentInterface{NewFlowSpecDestinationPrefix(24, "10.0.0.0")}) n1.SetPathLocalIdentifier(60) bits, err := n1.Serialize(opt) assert.Nil(err) diff --git a/packet/bgp/constant.go b/packet/bgp/constant.go index 5ea7b414e..587ba1f0d 100644 --- a/packet/bgp/constant.go +++ b/packet/bgp/constant.go @@ -35,7 +35,8 @@ const ( BGP_FSM_ESTABLISHED ) -// partially taken from http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml +// Protocol shows assigned Internet Protocol Numbers. +// Partially taken from http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml type Protocol int const ( @@ -103,8 +104,8 @@ var TCPFlagNameMap = map[TCPFlag]string{ TCP_FLAG_ECE: "E", } -// Prepares a sorted list of flags because map iterations does not happen -// in a consistent order in Golang. +// TCPSortedFlags prepares a sorted list of flags because map iterations does +// not happen in a consistent order in Golang. var TCPSortedFlags = []TCPFlag{ TCP_FLAG_FIN, TCP_FLAG_SYN, @@ -145,6 +146,8 @@ var BitmaskFlagOpNameMap = map[BitmaskFlagOp]string{ BITMASK_FLAG_OP_MATCH: "=", } +// BitmaskFlagOpValueMap shows the combinations of the bit flags for the Flow +// Spec Bitmask operator. // Note: Meaning of "" is different from that of the numeric operator because // RFC5575 says if the Match bit in the bitmask operand is set, it should be // "strictly" matching against the given value. @@ -194,8 +197,8 @@ var FragmentFlagNameMap = map[FragmentFlag]string{ FRAG_FLAG_LAST: "last-fragment", } -// Prepares a sorted list of flags because map iterations does not happen -// in a consistent order in Golang. +// FragmentSortedFlags prepares a sorted list of flags because map iterations +// does not happen in a consistent order in Golang. var FragmentSortedFlags = []FragmentFlag{ FRAG_FLAG_NOT, FRAG_FLAG_DONT, @@ -282,7 +285,8 @@ func (f DECNumOp) String() string { return strings.Join(ops, "") } -// Potentially taken from https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml +// EthernetType shows Ethernet Types. +// Partially taken from https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml type EthernetType int const ( diff --git a/packet/bgp/validate.go b/packet/bgp/validate.go index ecc67067a..e5b98cefe 100644 --- a/packet/bgp/validate.go +++ b/packet/bgp/validate.go @@ -8,7 +8,7 @@ import ( "strconv" ) -// Validator for BGPUpdate +// ValidateUpdateMsg validates the given BGPUpdate message. func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]BGPAddPathMode, isEBGP bool, isConfed bool) (bool, error) { var strongestError error @@ -177,9 +177,8 @@ func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]BGPAddPathM asParam, y := p.(*As4PathParam) if y { return asParam.Type - } else { - return p.(*AsPathParam).Type } + return p.(*AsPathParam).Type } if isEBGP { if isConfed { diff --git a/packet/bgp/validate_test.go b/packet/bgp/validate_test.go index 4228c2604..2774a308c 100644 --- a/packet/bgp/validate_test.go +++ b/packet/bgp/validate_test.go @@ -366,8 +366,8 @@ func Test_Validate_aspath(t *testing.T) { func Test_Validate_flowspec(t *testing.T) { assert := assert.New(t) cmp := make([]FlowSpecComponentInterface, 0) - cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) - cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) + cmp = append(cmp, NewFlowSpecDestinationPrefix(24, "10.0.0.0")) + cmp = append(cmp, NewFlowSpecSourcePrefix(24, "10.0.0.0")) item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20) @@ -393,8 +393,8 @@ func Test_Validate_flowspec(t *testing.T) { assert.Nil(err) cmp = make([]FlowSpecComponentInterface, 0) - cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) - cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) + cmp = append(cmp, NewFlowSpecSourcePrefix(24, "10.0.0.0")) + cmp = append(cmp, NewFlowSpecDestinationPrefix(24, "10.0.0.0")) n1 = NewFlowSpecIPv4Unicast(cmp) a = NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1}) // Swaps components order to reproduce the rules order violation. diff --git a/server/zclient.go b/server/zclient.go index 7c3116433..511774609 100644 --- a/server/zclient.go +++ b/server/zclient.go @@ -231,18 +231,18 @@ func newIPRouteBody(dst pathList) (body *zebra.IPRouteBody, isWithdraw bool) { switch path.GetRouteFamily() { case bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN: if path.GetRouteFamily() == bgp.RF_IPv4_UC { - prefix = path.GetNlri().(*bgp.IPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() + prefix = path.GetNlri().(*bgp.IPAddrPrefix).Prefix.To4() } else { - prefix = path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).IPAddrPrefixDefault.Prefix.To4() + prefix = path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix).Prefix.To4() } for _, p := range paths { nexthops = append(nexthops, p.GetNexthop().To4()) } case bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN: if path.GetRouteFamily() == bgp.RF_IPv6_UC { - prefix = path.GetNlri().(*bgp.IPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() + prefix = path.GetNlri().(*bgp.IPv6AddrPrefix).Prefix.To16() } else { - prefix = path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).IPAddrPrefixDefault.Prefix.To16() + prefix = path.GetNlri().(*bgp.LabeledVPNIPv6AddrPrefix).Prefix.To16() } for _, p := range paths { nexthops = append(nexthops, p.GetNexthop().To16())