summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go62
-rw-r--r--api/gobgp.proto20
-rw-r--r--gobgp/neighbor.go12
-rw-r--r--packet/bgp.go115
4 files changed, 207 insertions, 2 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 0b6689dd..cc2f5a4a 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -25,6 +25,7 @@ It has these top-level messages:
Nlri
TunnelEncapSubTLV
TunnelEncapTLV
+ PmsiTunnel
PathAttr
AsPath
Path
@@ -347,6 +348,44 @@ func (x TUNNEL_TYPE) String() string {
return proto.EnumName(TUNNEL_TYPE_name, int32(x))
}
+type PMSI_TUNNEL_TYPE int32
+
+const (
+ PMSI_TUNNEL_TYPE_NO_TUNNEL PMSI_TUNNEL_TYPE = 0
+ PMSI_TUNNEL_TYPE_RSVP_TE_P2MP PMSI_TUNNEL_TYPE = 1
+ PMSI_TUNNEL_TYPE_MLDP_P2MP PMSI_TUNNEL_TYPE = 2
+ PMSI_TUNNEL_TYPE_PIM_SSM_TREE PMSI_TUNNEL_TYPE = 3
+ PMSI_TUNNEL_TYPE_PIM_SM_TREE PMSI_TUNNEL_TYPE = 4
+ PMSI_TUNNEL_TYPE_BIDIR_PIM_TREE PMSI_TUNNEL_TYPE = 5
+ PMSI_TUNNEL_TYPE_INGRESS_REPL PMSI_TUNNEL_TYPE = 6
+ PMSI_TUNNEL_TYPE_MLDP_MP2MP PMSI_TUNNEL_TYPE = 7
+)
+
+var PMSI_TUNNEL_TYPE_name = map[int32]string{
+ 0: "NO_TUNNEL",
+ 1: "RSVP_TE_P2MP",
+ 2: "MLDP_P2MP",
+ 3: "PIM_SSM_TREE",
+ 4: "PIM_SM_TREE",
+ 5: "BIDIR_PIM_TREE",
+ 6: "INGRESS_REPL",
+ 7: "MLDP_MP2MP",
+}
+var PMSI_TUNNEL_TYPE_value = map[string]int32{
+ "NO_TUNNEL": 0,
+ "RSVP_TE_P2MP": 1,
+ "MLDP_P2MP": 2,
+ "PIM_SSM_TREE": 3,
+ "PIM_SM_TREE": 4,
+ "BIDIR_PIM_TREE": 5,
+ "INGRESS_REPL": 6,
+ "MLDP_MP2MP": 7,
+}
+
+func (x PMSI_TUNNEL_TYPE) String() string {
+ return proto.EnumName(PMSI_TUNNEL_TYPE_name, int32(x))
+}
+
type EVPN_TYPE int32
const (
@@ -421,6 +460,7 @@ const (
BGP_ATTR_TYPE_EXTENDED_COMMUNITIES BGP_ATTR_TYPE = 16
BGP_ATTR_TYPE_AS4_PATH BGP_ATTR_TYPE = 17
BGP_ATTR_TYPE_AS4_AGGREGATOR BGP_ATTR_TYPE = 18
+ BGP_ATTR_TYPE_PMSI_TUNNEL BGP_ATTR_TYPE = 22
BGP_ATTR_TYPE_TUNNEL_ENCAP BGP_ATTR_TYPE = 23
)
@@ -441,6 +481,7 @@ var BGP_ATTR_TYPE_name = map[int32]string{
16: "EXTENDED_COMMUNITIES",
17: "AS4_PATH",
18: "AS4_AGGREGATOR",
+ 22: "PMSI_TUNNEL",
23: "TUNNEL_ENCAP",
}
var BGP_ATTR_TYPE_value = map[string]int32{
@@ -460,6 +501,7 @@ var BGP_ATTR_TYPE_value = map[string]int32{
"EXTENDED_COMMUNITIES": 16,
"AS4_PATH": 17,
"AS4_AGGREGATOR": 18,
+ "PMSI_TUNNEL": 22,
"TUNNEL_ENCAP": 23,
}
@@ -756,6 +798,17 @@ func (m *TunnelEncapTLV) GetSubTlv() []*TunnelEncapSubTLV {
return nil
}
+type PmsiTunnel struct {
+ IsLeafInfoRequired bool `protobuf:"varint,1,opt,name=is_leaf_info_required" json:"is_leaf_info_required,omitempty"`
+ Type PMSI_TUNNEL_TYPE `protobuf:"varint,2,opt,name=type,enum=api.PMSI_TUNNEL_TYPE" json:"type,omitempty"`
+ Label uint32 `protobuf:"varint,3,opt,name=label" json:"label,omitempty"`
+ TunnelId string `protobuf:"bytes,4,opt,name=tunnel_id" json:"tunnel_id,omitempty"`
+}
+
+func (m *PmsiTunnel) Reset() { *m = PmsiTunnel{} }
+func (m *PmsiTunnel) String() string { return proto.CompactTextString(m) }
+func (*PmsiTunnel) ProtoMessage() {}
+
type PathAttr struct {
Type BGP_ATTR_TYPE `protobuf:"varint,1,opt,name=type,enum=api.BGP_ATTR_TYPE" json:"type,omitempty"`
Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"`
@@ -770,6 +823,7 @@ type PathAttr struct {
Cluster []string `protobuf:"bytes,11,rep,name=cluster" json:"cluster,omitempty"`
Nlri []*Nlri `protobuf:"bytes,12,rep,name=nlri" json:"nlri,omitempty"`
TunnelEncap []*TunnelEncapTLV `protobuf:"bytes,13,rep,name=tunnel_encap" json:"tunnel_encap,omitempty"`
+ PmsiTunnel *PmsiTunnel `protobuf:"bytes,14,opt,name=pmsi_tunnel" json:"pmsi_tunnel,omitempty"`
}
func (m *PathAttr) Reset() { *m = PathAttr{} }
@@ -804,6 +858,13 @@ func (m *PathAttr) GetTunnelEncap() []*TunnelEncapTLV {
return nil
}
+func (m *PathAttr) GetPmsiTunnel() *PmsiTunnel {
+ if m != nil {
+ return m.PmsiTunnel
+ }
+ return nil
+}
+
type AsPath struct {
SegmentType uint32 `protobuf:"varint,1,opt,name=segment_type" json:"segment_type,omitempty"`
Asns []uint32 `protobuf:"varint,2,rep,name=asns" json:"asns,omitempty"`
@@ -1169,6 +1230,7 @@ func init() {
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)
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 2c6c70d5..dce05d8b 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -187,6 +187,17 @@ enum TUNNEL_TYPE {
VXLAN_GRE = 12;
}
+enum PMSI_TUNNEL_TYPE {
+ NO_TUNNEL = 0;
+ RSVP_TE_P2MP = 1;
+ MLDP_P2MP = 2;
+ PIM_SSM_TREE = 3;
+ PIM_SM_TREE = 4;
+ BIDIR_PIM_TREE = 5;
+ INGRESS_REPL = 6;
+ MLDP_MP2MP = 7;
+}
+
enum EVPN_TYPE {
UNKNOWN_EVPN_TYPE = 0;
ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY = 1;
@@ -249,6 +260,13 @@ message TunnelEncapTLV {
repeated TunnelEncapSubTLV sub_tlv = 2;
}
+message PmsiTunnel {
+ bool is_leaf_info_required = 1;
+ PMSI_TUNNEL_TYPE type = 2;
+ uint32 label = 3;
+ string tunnel_id = 4;
+}
+
enum BGP_ATTR_TYPE {
UNKNOWN_ATTR = 0;
ORIGIN = 1;
@@ -266,6 +284,7 @@ enum BGP_ATTR_TYPE {
EXTENDED_COMMUNITIES = 16;
AS4_PATH = 17;
AS4_AGGREGATOR = 18;
+ PMSI_TUNNEL = 22;
TUNNEL_ENCAP = 23;
}
@@ -283,6 +302,7 @@ message PathAttr {
repeated string cluster = 11;
repeated Nlri nlri = 12;
repeated TunnelEncapTLV tunnel_encap = 13;
+ PmsiTunnel pmsi_tunnel = 14;
}
message AsPath {
diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go
index a3d8c27b..9935d1a0 100644
--- a/gobgp/neighbor.go
+++ b/gobgp/neighbor.go
@@ -305,6 +305,18 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool, isMonitor bool
s = append(s, fmt.Sprintf("{Originator: %v}", a.Originator))
case api.BGP_ATTR_TYPE_CLUSTER_LIST:
s = append(s, fmt.Sprintf("{Cluster: %v}", a.Cluster))
+ case api.BGP_ATTR_TYPE_PMSI_TUNNEL:
+ info := a.PmsiTunnel
+ s1 := bytes.NewBuffer(make([]byte, 0, 64))
+ s1.WriteString(fmt.Sprintf("{PMSI Tunnel: {Type: %s, ID: %s", info.Type, info.TunnelId))
+ if info.Label > 0 {
+ s1.WriteString(fmt.Sprintf(", Label: %d", info.Label))
+ }
+ if info.IsLeafInfoRequired {
+ s1.WriteString(fmt.Sprintf(", Leaf Info Required"))
+ }
+ s1.WriteString("}}")
+ s = append(s, s1.String())
case api.BGP_ATTR_TYPE_TUNNEL_ENCAP:
s1 := bytes.NewBuffer(make([]byte, 0, 64))
s1.WriteString("{Encap: ")
diff --git a/packet/bgp.go b/packet/bgp.go
index f5afc948..0c345ed2 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -134,6 +134,19 @@ const (
TUNNEL_TYPE_VXLAN_GRE TunnelType = 12
)
+type PmsiTunnelType uint8
+
+const (
+ PMSI_TUNNEL_TYPE_NO_TUNNEL PmsiTunnelType = 0
+ PMSI_TUNNEL_TYPE_RSVP_TE_P2MP PmsiTunnelType = 1
+ PMSI_TUNNEL_TYPE_MLDP_P2MP PmsiTunnelType = 2
+ PMSI_TUNNEL_TYPE_PIM_SSM_TREE PmsiTunnelType = 3
+ PMSI_TUNNEL_TYPE_PIM_SM_TREE PmsiTunnelType = 4
+ PMSI_TUNNEL_TYPE_BIDIR_PIM_TREE PmsiTunnelType = 5
+ PMSI_TUNNEL_TYPE_INGRESS_REPL PmsiTunnelType = 6
+ PMSI_TUNNEL_TYPE_MLDP_MP2MP PmsiTunnelType = 7
+)
+
type EncapSubTLVType uint8
const (
@@ -1765,8 +1778,8 @@ const (
_
_
_
- _
- BGP_ATTR_TYPE_TUNNEL_ENCAP // = 23
+ BGP_ATTR_TYPE_PMSI_TUNNEL // = 22
+ BGP_ATTR_TYPE_TUNNEL_ENCAP
)
// NOTIFICATION Error Code RFC 4271 4.5.
@@ -1856,6 +1869,7 @@ var pathAttrFlags map[BGPAttrType]BGPAttrFlag = map[BGPAttrType]BGPAttrFlag{
BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
BGP_ATTR_TYPE_AS4_PATH: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
BGP_ATTR_TYPE_AS4_AGGREGATOR: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
+ BGP_ATTR_TYPE_PMSI_TUNNEL: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
BGP_ATTR_TYPE_TUNNEL_ENCAP: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
}
@@ -3666,6 +3680,101 @@ func NewPathAttributeTunnelEncap(value []*TunnelEncapTLV) *PathAttributeTunnelEn
}
}
+type PmsiTunnelIDInterface interface {
+ Serialize() ([]byte, error)
+ String() string
+}
+
+type DefaultPmsiTunnelID struct {
+ Value []byte
+}
+
+func (i *DefaultPmsiTunnelID) Serialize() ([]byte, error) {
+ return i.Value, nil
+}
+
+func (i *DefaultPmsiTunnelID) String() string {
+ return string(i.Value)
+}
+
+type IngressReplTunnelID struct {
+ Value net.IP
+}
+
+func (i *IngressReplTunnelID) Serialize() ([]byte, error) {
+ if i.Value.To4() != nil {
+ return []byte(i.Value.To4()), nil
+ }
+ return []byte(i.Value), nil
+}
+
+func (i *IngressReplTunnelID) String() string {
+ return i.Value.String()
+}
+
+type PathAttributePmsiTunnel struct {
+ PathAttribute
+ IsLeafInfoRequired bool
+ TunnelType PmsiTunnelType
+ Label uint32
+ TunnelID PmsiTunnelIDInterface
+}
+
+func (p *PathAttributePmsiTunnel) DecodeFromBytes(data []byte) error {
+ err := p.PathAttribute.DecodeFromBytes(data)
+ if err != nil {
+ return err
+ }
+ if len(p.PathAttribute.Value) < 5 {
+ eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
+ eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST)
+ return NewMessageError(eCode, eSubCode, nil, "PMSI Tunnel length is incorrect")
+ }
+
+ if (p.PathAttribute.Value[0] & 0x01) > 0 {
+ p.IsLeafInfoRequired = true
+ }
+ p.TunnelType = PmsiTunnelType(p.PathAttribute.Value[1])
+ p.Label = labelDecode(p.PathAttribute.Value[2:5])
+
+ switch p.TunnelType {
+ case PMSI_TUNNEL_TYPE_INGRESS_REPL:
+ p.TunnelID = &IngressReplTunnelID{net.IP(p.PathAttribute.Value[5:])}
+ default:
+ p.TunnelID = &DefaultPmsiTunnelID{p.PathAttribute.Value[5:]}
+ }
+ return nil
+}
+
+func (p *PathAttributePmsiTunnel) Serialize() ([]byte, error) {
+ buf := make([]byte, 2)
+ if p.IsLeafInfoRequired {
+ buf[0] = 0x01
+ }
+ buf[1] = byte(p.TunnelType)
+ lbuf := make([]byte, 3)
+ labelSerialize(p.Label, lbuf)
+ buf = append(buf, lbuf...)
+ ibuf, err := p.TunnelID.Serialize()
+ if err != nil {
+ return nil, err
+ }
+ buf = append(buf, ibuf...)
+ return buf, nil
+}
+
+func (p *PathAttributePmsiTunnel) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_PMSI_TUNNEL,
+ PmsiTunnel: &api.PmsiTunnel{
+ IsLeafInfoRequired: p.IsLeafInfoRequired,
+ Type: api.PMSI_TUNNEL_TYPE(p.TunnelType),
+ Label: p.Label,
+ TunnelId: p.TunnelID.String(),
+ },
+ }
+}
+
type PathAttributeUnknown struct {
PathAttribute
}
@@ -3720,6 +3829,8 @@ func GetPathAttribute(data []byte) (PathAttributeInterface, error) {
return &PathAttributeAs4Aggregator{}, nil
case BGP_ATTR_TYPE_TUNNEL_ENCAP:
return &PathAttributeTunnelEncap{}, nil
+ case BGP_ATTR_TYPE_PMSI_TUNNEL:
+ return &PathAttributePmsiTunnel{}, nil
}
return &PathAttributeUnknown{}, nil
}