summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go128
-rw-r--r--api/gobgp.proto36
-rw-r--r--packet/bgp.go178
-rw-r--r--packet/bgp_test.go3
4 files changed, 263 insertions, 82 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index a7e0d90d..71e3f454 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -292,55 +292,6 @@ func (x Origin) String() string {
return proto.EnumName(Origin_name, int32(x))
}
-type EXTENDED_COMMUNITIE_TYPE int32
-
-const (
- EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC EXTENDED_COMMUNITIE_TYPE = 0
- EXTENDED_COMMUNITIE_TYPE_IP4_SPECIFIC EXTENDED_COMMUNITIE_TYPE = 1
- EXTENDED_COMMUNITIE_TYPE_FOUR_OCTET_AS_SPECIFIC EXTENDED_COMMUNITIE_TYPE = 2
- EXTENDED_COMMUNITIE_TYPE_OPAQUE EXTENDED_COMMUNITIE_TYPE = 3
-)
-
-var EXTENDED_COMMUNITIE_TYPE_name = map[int32]string{
- 0: "TWO_OCTET_AS_SPECIFIC",
- 1: "IP4_SPECIFIC",
- 2: "FOUR_OCTET_AS_SPECIFIC",
- 3: "OPAQUE",
-}
-var EXTENDED_COMMUNITIE_TYPE_value = map[string]int32{
- "TWO_OCTET_AS_SPECIFIC": 0,
- "IP4_SPECIFIC": 1,
- "FOUR_OCTET_AS_SPECIFIC": 2,
- "OPAQUE": 3,
-}
-
-func (x EXTENDED_COMMUNITIE_TYPE) String() string {
- return proto.EnumName(EXTENDED_COMMUNITIE_TYPE_name, int32(x))
-}
-
-type EXTENDED_COMMUNITIE_SUBTYPE int32
-
-const (
- EXTENDED_COMMUNITIE_SUBTYPE_ORIGIN_VALIDATION EXTENDED_COMMUNITIE_SUBTYPE = 0
- EXTENDED_COMMUNITIE_SUBTYPE_ROUTE_TARGET EXTENDED_COMMUNITIE_SUBTYPE = 2
- EXTENDED_COMMUNITIE_SUBTYPE_ROUTE_ORIGIN EXTENDED_COMMUNITIE_SUBTYPE = 3
-)
-
-var EXTENDED_COMMUNITIE_SUBTYPE_name = map[int32]string{
- 0: "ORIGIN_VALIDATION",
- 2: "ROUTE_TARGET",
- 3: "ROUTE_ORIGIN",
-}
-var EXTENDED_COMMUNITIE_SUBTYPE_value = map[string]int32{
- "ORIGIN_VALIDATION": 0,
- "ROUTE_TARGET": 2,
- "ROUTE_ORIGIN": 3,
-}
-
-func (x EXTENDED_COMMUNITIE_SUBTYPE) String() string {
- return proto.EnumName(EXTENDED_COMMUNITIE_SUBTYPE_name, int32(x))
-}
-
type TUNNEL_TYPE int32
const (
@@ -563,6 +514,64 @@ func (x Error_ErrorCode) String() string {
return proto.EnumName(Error_ErrorCode_name, int32(x))
}
+type ExtendedCommunity_Type int32
+
+const (
+ ExtendedCommunity_TWO_OCTET_AS_SPECIFIC ExtendedCommunity_Type = 0
+ ExtendedCommunity_IP4_SPECIFIC ExtendedCommunity_Type = 1
+ ExtendedCommunity_FOUR_OCTET_AS_SPECIFIC ExtendedCommunity_Type = 2
+ ExtendedCommunity_OPAQUE ExtendedCommunity_Type = 3
+ ExtendedCommunity_EVPN ExtendedCommunity_Type = 4
+)
+
+var ExtendedCommunity_Type_name = map[int32]string{
+ 0: "TWO_OCTET_AS_SPECIFIC",
+ 1: "IP4_SPECIFIC",
+ 2: "FOUR_OCTET_AS_SPECIFIC",
+ 3: "OPAQUE",
+ 4: "EVPN",
+}
+var ExtendedCommunity_Type_value = map[string]int32{
+ "TWO_OCTET_AS_SPECIFIC": 0,
+ "IP4_SPECIFIC": 1,
+ "FOUR_OCTET_AS_SPECIFIC": 2,
+ "OPAQUE": 3,
+ "EVPN": 4,
+}
+
+func (x ExtendedCommunity_Type) String() string {
+ return proto.EnumName(ExtendedCommunity_Type_name, int32(x))
+}
+
+type ExtendedCommunity_Subtype int32
+
+const (
+ ExtendedCommunity_ORIGIN_VALIDATION ExtendedCommunity_Subtype = 0
+ ExtendedCommunity_ROUTE_TARGET ExtendedCommunity_Subtype = 2
+ ExtendedCommunity_ROUTE_ORIGIN ExtendedCommunity_Subtype = 3
+ ExtendedCommunity_ESI_LABEL ExtendedCommunity_Subtype = 4
+ ExtendedCommunity_MAC_MOBILITY ExtendedCommunity_Subtype = 5
+)
+
+var ExtendedCommunity_Subtype_name = map[int32]string{
+ 0: "ORIGIN_VALIDATION",
+ 2: "ROUTE_TARGET",
+ 3: "ROUTE_ORIGIN",
+ 4: "ESI_LABEL",
+ 5: "MAC_MOBILITY",
+}
+var ExtendedCommunity_Subtype_value = map[string]int32{
+ "ORIGIN_VALIDATION": 0,
+ "ROUTE_TARGET": 2,
+ "ROUTE_ORIGIN": 3,
+ "ESI_LABEL": 4,
+ "MAC_MOBILITY": 5,
+}
+
+func (x ExtendedCommunity_Subtype) String() string {
+ return proto.EnumName(ExtendedCommunity_Subtype_name, int32(x))
+}
+
type Error struct {
Code Error_ErrorCode `protobuf:"varint,1,opt,name=code,enum=api.Error_ErrorCode" json:"code,omitempty"`
Msg string `protobuf:"bytes,2,opt,name=msg" json:"msg,omitempty"`
@@ -733,12 +742,17 @@ func (m *Aggregator) String() string { return proto.CompactTextString(m) }
func (*Aggregator) ProtoMessage() {}
type ExtendedCommunity struct {
- Type EXTENDED_COMMUNITIE_TYPE `protobuf:"varint,1,opt,name=type,enum=api.EXTENDED_COMMUNITIE_TYPE" json:"type,omitempty"`
- Subtype EXTENDED_COMMUNITIE_SUBTYPE `protobuf:"varint,2,opt,name=subtype,enum=api.EXTENDED_COMMUNITIE_SUBTYPE" json:"subtype,omitempty"`
- IsTransitive bool `protobuf:"varint,3,opt,name=is_transitive" json:"is_transitive,omitempty"`
- Asn uint32 `protobuf:"varint,4,opt,name=asn" json:"asn,omitempty"`
- Ipv4 string `protobuf:"bytes,5,opt,name=ipv4" json:"ipv4,omitempty"`
- LocalAdmin uint32 `protobuf:"varint,6,opt,name=local_admin" json:"local_admin,omitempty"`
+ Type ExtendedCommunity_Type `protobuf:"varint,1,opt,name=type,enum=api.ExtendedCommunity_Type" json:"type,omitempty"`
+ Subtype ExtendedCommunity_Subtype `protobuf:"varint,2,opt,name=subtype,enum=api.ExtendedCommunity_Subtype" json:"subtype,omitempty"`
+ IsTransitive bool `protobuf:"varint,3,opt,name=is_transitive" json:"is_transitive,omitempty"`
+ Asn uint32 `protobuf:"varint,4,opt,name=asn" json:"asn,omitempty"`
+ Ipv4 string `protobuf:"bytes,5,opt,name=ipv4" json:"ipv4,omitempty"`
+ LocalAdmin uint32 `protobuf:"varint,6,opt,name=local_admin" json:"local_admin,omitempty"`
+ IsSingleActive bool `protobuf:"varint,7,opt,name=is_single_active" json:"is_single_active,omitempty"`
+ Label uint32 `protobuf:"varint,8,opt,name=label" json:"label,omitempty"`
+ EsImport string `protobuf:"bytes,9,opt,name=es_import" json:"es_import,omitempty"`
+ Sequence uint32 `protobuf:"varint,10,opt,name=sequence" json:"sequence,omitempty"`
+ IsSticky bool `protobuf:"varint,11,opt,name=is_sticky" json:"is_sticky,omitempty"`
}
func (m *ExtendedCommunity) Reset() { *m = ExtendedCommunity{} }
@@ -1398,14 +1412,14 @@ func init() {
proto.RegisterEnum("api.ROUTE_DISTINGUISHER_TYPE", ROUTE_DISTINGUISHER_TYPE_name, ROUTE_DISTINGUISHER_TYPE_value)
proto.RegisterEnum("api.BGP_CAPABILITY", BGP_CAPABILITY_name, BGP_CAPABILITY_value)
proto.RegisterEnum("api.Origin", Origin_name, Origin_value)
- proto.RegisterEnum("api.EXTENDED_COMMUNITIE_TYPE", EXTENDED_COMMUNITIE_TYPE_name, EXTENDED_COMMUNITIE_TYPE_value)
- proto.RegisterEnum("api.EXTENDED_COMMUNITIE_SUBTYPE", EXTENDED_COMMUNITIE_SUBTYPE_name, EXTENDED_COMMUNITIE_SUBTYPE_value)
proto.RegisterEnum("api.TUNNEL_TYPE", TUNNEL_TYPE_name, TUNNEL_TYPE_value)
proto.RegisterEnum("api.PMSI_TUNNEL_TYPE", PMSI_TUNNEL_TYPE_name, PMSI_TUNNEL_TYPE_value)
proto.RegisterEnum("api.EVPN_TYPE", EVPN_TYPE_name, EVPN_TYPE_value)
proto.RegisterEnum("api.ENCAP_SUBTLV_TYPE", ENCAP_SUBTLV_TYPE_name, ENCAP_SUBTLV_TYPE_value)
proto.RegisterEnum("api.BGP_ATTR_TYPE", BGP_ATTR_TYPE_name, BGP_ATTR_TYPE_value)
proto.RegisterEnum("api.Error_ErrorCode", Error_ErrorCode_name, Error_ErrorCode_value)
+ proto.RegisterEnum("api.ExtendedCommunity_Type", ExtendedCommunity_Type_name, ExtendedCommunity_Type_value)
+ proto.RegisterEnum("api.ExtendedCommunity_Subtype", ExtendedCommunity_Subtype_name, ExtendedCommunity_Subtype_value)
}
// Client API for Grpc service
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 84844214..fe3d31fe 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -178,26 +178,32 @@ message Aggregator {
string address = 2;
}
-enum EXTENDED_COMMUNITIE_TYPE {
- TWO_OCTET_AS_SPECIFIC = 0;
- IP4_SPECIFIC = 1;
- FOUR_OCTET_AS_SPECIFIC = 2;
- OPAQUE = 3;
-}
-
-enum EXTENDED_COMMUNITIE_SUBTYPE {
- ORIGIN_VALIDATION = 0;
- ROUTE_TARGET = 2;
- ROUTE_ORIGIN = 3;
-}
-
message ExtendedCommunity {
- EXTENDED_COMMUNITIE_TYPE type = 1;
- EXTENDED_COMMUNITIE_SUBTYPE subtype = 2;
+ enum Type {
+ TWO_OCTET_AS_SPECIFIC = 0;
+ IP4_SPECIFIC = 1;
+ FOUR_OCTET_AS_SPECIFIC = 2;
+ OPAQUE = 3;
+ EVPN = 4;
+ }
+ Type type = 1;
+ enum Subtype {
+ ORIGIN_VALIDATION = 0;
+ ROUTE_TARGET = 2;
+ ROUTE_ORIGIN = 3;
+ ESI_LABEL = 4;
+ MAC_MOBILITY = 5;
+ }
+ Subtype subtype = 2;
bool is_transitive = 3;
uint32 asn = 4;
string ipv4 = 5;
uint32 local_admin = 6;
+ bool is_single_active = 7;
+ uint32 label = 8;
+ string es_import = 9;
+ uint32 sequence = 10;
+ bool is_sticky = 11;
}
enum TUNNEL_TYPE {
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{