summaryrefslogtreecommitdiffhomepage
path: root/packet
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-07-29 16:15:06 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-08-05 17:24:36 +0900
commit2017bdc7a9452d4a66dd062016f1b68fbf4ef09b (patch)
treef49e3cc2b126b3a83daa93fee292ee43ebb3da36 /packet
parentb04d28518aa00b0d7faec7efdb729b78b90c529e (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.go178
-rw-r--r--packet/bgp_test.go3
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{