summaryrefslogtreecommitdiffhomepage
path: root/packet
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-04-29 09:40:33 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-07-01 13:51:31 +0900
commit2cd6dbe946b2b7b1bd88d286822fd42f5ec9b2ad (patch)
treeebdd7c0cbd4e9a3122b62ccff67340ca0b2d3ebb /packet
parent84a495d844d03a2da209cca722a2c2b2da7606f3 (diff)
bgp: add PMSI Tunnel Path Attribute(RFC6514) serializer/decoder
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'packet')
-rw-r--r--packet/bgp.go115
1 files changed, 113 insertions, 2 deletions
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
}