Skip to content

Commit

Permalink
Add initial support for evpn subtype 4
Browse files Browse the repository at this point in the history
  • Loading branch information
Mrflatt authored and fujita committed Dec 9, 2023
1 parent 08529d6 commit 7ddcd29
Showing 1 changed file with 118 additions and 6 deletions.
124 changes: 118 additions & 6 deletions pkg/packet/bgp/bgp.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,11 @@ const (
EC_SUBTYPE_L2_INFO ExtendedCommunityAttrSubType = 0x0A // EC_TYPE: 0x80
EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6 ExtendedCommunityAttrSubType = 0x0B // EC_TYPE: 0x80

EC_SUBTYPE_MAC_MOBILITY ExtendedCommunityAttrSubType = 0x00 // EC_TYPE: 0x06
EC_SUBTYPE_ESI_LABEL ExtendedCommunityAttrSubType = 0x01 // EC_TYPE: 0x06
EC_SUBTYPE_ES_IMPORT ExtendedCommunityAttrSubType = 0x02 // EC_TYPE: 0x06
EC_SUBTYPE_ROUTER_MAC ExtendedCommunityAttrSubType = 0x03 // EC_TYPE: 0x06
EC_SUBTYPE_MAC_MOBILITY ExtendedCommunityAttrSubType = 0x00 // EC_TYPE: 0x06
EC_SUBTYPE_ESI_LABEL ExtendedCommunityAttrSubType = 0x01 // EC_TYPE: 0x06
EC_SUBTYPE_ES_IMPORT ExtendedCommunityAttrSubType = 0x02 // EC_TYPE: 0x06
EC_SUBTYPE_ROUTER_MAC ExtendedCommunityAttrSubType = 0x03 // EC_TYPE: 0x06
EC_SUBTYPE_L2_ATTRIBUTES ExtendedCommunityAttrSubType = 0x04 // EC_TYPE: 0x06

EC_SUBTYPE_UUID_BASED_RT ExtendedCommunityAttrSubType = 0x11
)
Expand Down Expand Up @@ -3142,7 +3143,7 @@ func (er *EVPNIPPrefixRoute) DecodeFromBytes(data []byte) error {
if er.Label, err = labelDecode(data[offset : offset+3]); err != nil {
return err
}
//offset += 3
// offset += 3

return nil
}
Expand Down Expand Up @@ -9876,7 +9877,7 @@ const (
BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE
BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION
BGP_ERROR_SUB_OUT_OF_RESOURCES
BGP_ERROR_SUB_HARD_RESET //draft-ietf-idr-bgp-gr-notification-07
BGP_ERROR_SUB_HARD_RESET // draft-ietf-idr-bgp-gr-notification-07
)

// Constants for BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN and BGP_ERROR_SUB_ADMINISTRATIVE_RESET
Expand Down Expand Up @@ -12254,6 +12255,98 @@ func NewRoutersMacExtended(mac string) *RouterMacExtended {
}
}

type Layer2AttributesExtended struct {
HasCILabel bool
HasFlowLabel bool
HasControlWord bool
IsPrimaryPe bool
IsBackupPe bool
Mtu uint16
}

type EvpnControlFlag uint8

const (
BACKUP_PE EvpnControlFlag = 1 << 0
PRIMARY_PE EvpnControlFlag = 1 << 1
CONTROL_WORD EvpnControlFlag = 1 << 2
FLOW_LABEL EvpnControlFlag = 1 << 3
CI_LABEL EvpnControlFlag = 1 << 4
)

func (e *Layer2AttributesExtended) Serialize() ([]byte, error) {
buf := make([]byte, 8)
buf[0] = byte(EC_TYPE_EVPN)
buf[1] = byte(EC_SUBTYPE_L2_ATTRIBUTES)

if e.IsBackupPe {
buf[3] |= uint8(BACKUP_PE)
} else if e.IsPrimaryPe {
buf[3] |= uint8(PRIMARY_PE)
}
if e.HasControlWord {
buf[3] |= uint8(CONTROL_WORD)
}
if e.HasFlowLabel {
buf[3] |= uint8(FLOW_LABEL)
}
if e.HasCILabel {
buf[3] |= uint8(CI_LABEL)
}
binary.BigEndian.PutUint16(buf[4:6], e.Mtu)
return buf, nil
}

func (e *Layer2AttributesExtended) String() string {
buf := bytes.NewBuffer(make([]byte, 0, 32))
buf.WriteString("evpn-l2-info: ")
if e.IsPrimaryPe {
buf.WriteString("is-primary-pe, ")
}
if e.IsBackupPe {
buf.WriteString("is-backup-pe, ")
}
if e.HasControlWord {
buf.WriteString("control-word, ")
}
if e.HasFlowLabel {
buf.WriteString("flow-label, ")
}
if e.HasCILabel {
buf.WriteString("ci-label, ")
}

buf.WriteString("mtu " + strconv.FormatUint(uint64(e.Mtu), 10))
return buf.String()
}

func (e *Layer2AttributesExtended) MarshalJSON() ([]byte, error) {
t, s := e.GetTypes()
return json.Marshal(struct {
Type ExtendedCommunityAttrType `json:"type"`
Subtype ExtendedCommunityAttrSubType `json:"subtype"`
CILabel bool `json:"ci_label,omitempty"`
FlowLabel bool `json:"flow_label,omitempty"`
ControlWord bool `json:"control_word,omitempty"`
PrimaryPe bool `json:"is_primary_pe,omitempty"`
BackupPe bool `json:"is_backup_pe,omitempty"`
Mtu uint16 `json:"mtu"`
}{
Type: t,
Subtype: s,
CILabel: e.HasCILabel,
FlowLabel: e.HasFlowLabel,
ControlWord: e.HasControlWord,
PrimaryPe: e.IsPrimaryPe,
BackupPe: e.IsBackupPe,
Mtu: e.Mtu,
})
}

func (e *Layer2AttributesExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) {
return EC_TYPE_EVPN, EC_SUBTYPE_L2_ATTRIBUTES
}

func parseEvpnExtended(data []byte) (ExtendedCommunityInterface, error) {
if ExtendedCommunityAttrType(data[0]) != EC_TYPE_EVPN {
return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("ext comm type is not EC_TYPE_EVPN: %d", data[0]))
Expand Down Expand Up @@ -12288,6 +12381,21 @@ func parseEvpnExtended(data []byte) (ExtendedCommunityInterface, error) {
return &RouterMacExtended{
Mac: net.HardwareAddr(data[2:8]),
}, nil
case EC_SUBTYPE_L2_ATTRIBUTES:
if flags := data[3]; flags == 0 {
return &Layer2AttributesExtended{
Mtu: binary.BigEndian.Uint16(data[4:6]),
}, nil
} else {
return &Layer2AttributesExtended{
HasCILabel: flags&uint8(CI_LABEL) > 0,
HasFlowLabel: flags&uint8(FLOW_LABEL) > 0,
HasControlWord: flags&uint8(CONTROL_WORD) > 0,
IsPrimaryPe: flags&uint8(PRIMARY_PE) > 0,
IsBackupPe: flags&uint8(BACKUP_PE) > 0,
Mtu: binary.BigEndian.Uint16(data[4:6]),
}, nil
}
}
return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("unknown evpn subtype: %d", subType))
}
Expand Down Expand Up @@ -14855,6 +14963,10 @@ func (e *RouterMacExtended) Flat() map[string]string {
return map[string]string{}
}

func (e *Layer2AttributesExtended) Flat() map[string]string {
return map[string]string{}
}

func (e *TrafficRateExtended) Flat() map[string]string {
return map[string]string{}
}
Expand Down

0 comments on commit 7ddcd29

Please sign in to comment.