diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-07-29 16:15:06 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-05 17:24:36 +0900 |
commit | 2017bdc7a9452d4a66dd062016f1b68fbf4ef09b (patch) | |
tree | f49e3cc2b126b3a83daa93fee292ee43ebb3da36 /packet | |
parent | b04d28518aa00b0d7faec7efdb729b78b90c529e (diff) |
api/packet: add evpn extended community structs
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'packet')
-rw-r--r-- | packet/bgp.go | 178 | ||||
-rw-r--r-- | packet/bgp_test.go | 3 |
2 files changed, 171 insertions, 10 deletions
diff --git a/packet/bgp.go b/packet/bgp.go index 7fd4f9e6..450d0864 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -118,9 +118,9 @@ const ( EC_SUBTYPE_FLOWSPEC_REDIRECT ExtendedCommunityAttrSubType = 0x08 EC_SUBTYPE_FLOWSPEC_TRAFFIC_REMARK ExtendedCommunityAttrSubType = 0x09 - EC_SUBTYPE_MAC_MOBILITY ExtendedCommunityAttrSubType = 0x00 - EC_SUBTYPE_ESI_MPLS_LABEL ExtendedCommunityAttrSubType = 0x01 - EC_SUBTYPE_ES_IMPORT ExtendedCommunityAttrSubType = 0x02 + EC_SUBTYPE_MAC_MOBILITY ExtendedCommunityAttrSubType = 0x00 + EC_SUBTYPE_ESI_LABEL ExtendedCommunityAttrSubType = 0x01 + EC_SUBTYPE_ES_IMPORT ExtendedCommunityAttrSubType = 0x02 ) type TunnelType uint16 @@ -3106,8 +3106,8 @@ func (e *TwoOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Exte func (e *TwoOctetAsSpecificExtended) ToApiStruct() *api.ExtendedCommunity { return &api.ExtendedCommunity{ - Type: api.EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC, - Subtype: api.EXTENDED_COMMUNITIE_SUBTYPE(e.SubType), + Type: api.ExtendedCommunity_TWO_OCTET_AS_SPECIFIC, + Subtype: api.ExtendedCommunity_Subtype(e.SubType), IsTransitive: e.IsTransitive, Asn: uint32(e.AS), LocalAdmin: e.LocalAdmin, @@ -3157,8 +3157,8 @@ func (e *IPv4AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Ext func (e *IPv4AddressSpecificExtended) ToApiStruct() *api.ExtendedCommunity { return &api.ExtendedCommunity{ - Type: api.EXTENDED_COMMUNITIE_TYPE_IP4_SPECIFIC, - Subtype: api.EXTENDED_COMMUNITIE_SUBTYPE(e.SubType), + Type: api.ExtendedCommunity_IP4_SPECIFIC, + Subtype: api.ExtendedCommunity_Subtype(e.SubType), IsTransitive: e.IsTransitive, Ipv4: e.IPv4.String(), LocalAdmin: uint32(e.LocalAdmin), @@ -3203,8 +3203,8 @@ func (e *FourOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, Ext func (e *FourOctetAsSpecificExtended) ToApiStruct() *api.ExtendedCommunity { return &api.ExtendedCommunity{ - Type: api.EXTENDED_COMMUNITIE_TYPE_FOUR_OCTET_AS_SPECIFIC, - Subtype: api.EXTENDED_COMMUNITIE_SUBTYPE(e.SubType), + Type: api.ExtendedCommunity_FOUR_OCTET_AS_SPECIFIC, + Subtype: api.ExtendedCommunity_Subtype(e.SubType), IsTransitive: e.IsTransitive, Asn: e.AS, LocalAdmin: uint32(e.LocalAdmin), @@ -3340,7 +3340,7 @@ func (e *OpaqueExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunit func (e *OpaqueExtended) ToApiStruct() *api.ExtendedCommunity { return &api.ExtendedCommunity{ - Type: api.EXTENDED_COMMUNITIE_TYPE_OPAQUE, + Type: api.ExtendedCommunity_OPAQUE, } } @@ -3350,6 +3350,162 @@ func NewOpaqueExtended(isTransitive bool) *OpaqueExtended { } } +type ESILabelExtended struct { + Label uint32 + IsSingleActive bool +} + +func (e *ESILabelExtended) Serialize() ([]byte, error) { + buf := make([]byte, 8) + buf[0] = byte(EC_TYPE_EVPN) + buf[1] = byte(EC_SUBTYPE_ESI_LABEL) + if e.IsSingleActive { + buf[2] = byte(1) + } + buf[3] = 0 + buf[4] = 0 + buf[5] = byte((e.Label >> 16) & 0xff) + buf[6] = byte((e.Label >> 8) & 0xff) + buf[7] = byte(e.Label & 0xff) + return buf, nil +} + +func (e *ESILabelExtended) String() string { + return fmt.Sprintf("ESI LABEL: Label [%d] IsSingleActive [%t]", e.Label, e.IsSingleActive) +} + +func (e *ESILabelExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_ESI_LABEL +} + +func (e *ESILabelExtended) ToApiStruct() *api.ExtendedCommunity { + return &api.ExtendedCommunity{ + Type: api.ExtendedCommunity_EVPN, + Subtype: api.ExtendedCommunity_ESI_LABEL, + IsSingleActive: e.IsSingleActive, + Label: e.Label, + } +} + +func NewESILabelExtended(label uint32, isSingleActive bool) *ESILabelExtended { + return &ESILabelExtended{ + Label: label, + IsSingleActive: isSingleActive, + } +} + +type ESImportRouteTarget struct { + ESImport net.HardwareAddr +} + +func (e *ESImportRouteTarget) Serialize() ([]byte, error) { + buf := make([]byte, 8) + buf[0] = byte(EC_TYPE_EVPN) + buf[1] = byte(EC_SUBTYPE_ES_IMPORT) + copy(buf[2:], e.ESImport) + return buf, nil +} + +func (e *ESImportRouteTarget) String() string { + return fmt.Sprintf("ES-IMPORT ROUTE TARGET: ES-Import [%s]", e.ESImport.String()) +} + +func (e *ESImportRouteTarget) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_ES_IMPORT +} + +func (e *ESImportRouteTarget) ToApiStruct() *api.ExtendedCommunity { + return &api.ExtendedCommunity{ + Type: api.ExtendedCommunity_EVPN, + Subtype: api.ExtendedCommunity_ROUTE_TARGET, + EsImport: e.ESImport.String(), + } +} + +func NewESImportRouteTarget(mac string) *ESImportRouteTarget { + esImport, err := net.ParseMAC(mac) + if err != nil { + return nil + } + return &ESImportRouteTarget{ + ESImport: esImport, + } +} + +type MacMobilityExtended struct { + Sequence uint32 + IsSticky bool +} + +func (e *MacMobilityExtended) Serialize() ([]byte, error) { + buf := make([]byte, 8) + buf[0] = byte(EC_TYPE_EVPN) + buf[1] = byte(EC_SUBTYPE_MAC_MOBILITY) + if e.IsSticky { + buf[2] = byte(1) + } + binary.BigEndian.PutUint32(buf[4:], e.Sequence) + return buf, nil +} + +func (e *MacMobilityExtended) String() string { + return fmt.Sprintf("MAC MOBILITY: Seq [%d] IsSticky [%t]", e.Sequence, e.IsSticky) +} + +func (e *MacMobilityExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { + return EC_TYPE_EVPN, EC_SUBTYPE_MAC_MOBILITY +} + +func (e *MacMobilityExtended) ToApiStruct() *api.ExtendedCommunity { + return &api.ExtendedCommunity{ + Type: api.ExtendedCommunity_EVPN, + Subtype: api.ExtendedCommunity_MAC_MOBILITY, + Sequence: e.Sequence, + IsSticky: e.IsSticky, + } +} + +func NewMacMobilityExtended(seq uint32, isSticky bool) *MacMobilityExtended { + return &MacMobilityExtended{ + Sequence: seq, + IsSticky: isSticky, + } +} + +func parseEvpnExtended(data []byte) (ExtendedCommunityInterface, error) { + if ExtendedCommunityAttrType(data[0]) != EC_TYPE_EVPN { + return nil, fmt.Errorf("ext comm type is not EC_TYPE_EVPN: %d", data[0]) + } + subType := ExtendedCommunityAttrSubType(data[1]) + switch subType { + case EC_SUBTYPE_ESI_LABEL: + var isSingleActive bool + if data[2] > 0 { + isSingleActive = true + } + label := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7]) + return &ESILabelExtended{ + IsSingleActive: isSingleActive, + Label: label, + }, nil + case EC_SUBTYPE_ES_IMPORT: + return &ESImportRouteTarget{ + ESImport: net.HardwareAddr(data[2:8]), + }, nil + case EC_SUBTYPE_MAC_MOBILITY: + var isSticky bool + if data[2] > 0 { + isSticky = true + } + seq := binary.BigEndian.Uint32(data[4:8]) + return &MacMobilityExtended{ + Sequence: seq, + IsSticky: isSticky, + }, nil + } + return nil, fmt.Errorf("unknown subtype: %d", subType) +} + type UnknownExtended struct { Type BGPAttrType Value []byte @@ -3424,6 +3580,8 @@ func parseExtended(data []byte) (ExtendedCommunityInterface, error) { e := NewOpaqueExtended(transitive) err := e.DecodeFromBytes(data[1:8]) return e, err + case EC_TYPE_EVPN: + return parseEvpnExtended(data) default: e := &UnknownExtended{} e.Type = BGPAttrType(data[0]) diff --git a/packet/bgp_test.go b/packet/bgp_test.go index 983914f1..528b3c4c 100644 --- a/packet/bgp_test.go +++ b/packet/bgp_test.go @@ -67,6 +67,9 @@ func update() *BGPMessage { Value: &DefaultOpaqueExtendedValue{[]byte{0, 1, 2, 3, 4, 5, 6, 7}}, }, &UnknownExtended{Type: 99, Value: []byte{0, 1, 2, 3, 4, 5, 6, 7}}, + NewESILabelExtended(1000, true), + NewESImportRouteTarget("11:22:33:44:55:66"), + NewMacMobilityExtended(123, false), } mp_nlri := []AddrPrefixInterface{ |