summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSerguei Bezverkhi <sbezverk@cisco.com>2020-05-04 08:46:17 -0400
committerSerguei Bezverkhi <sbezverk@cisco.com>2020-05-04 08:46:17 -0400
commitf11ece918f233e62a98c0d40b4ec3a90417aa3a6 (patch)
tree1ae3b5d543d3de18f529fd8a331dd5ed19bd4cdb
parentdf76b278eee6799463e0feec8396fb66a3280bb2 (diff)
adding prefix_sid_attr
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
-rw-r--r--pkg/packet/bgp/bgp.go234
-rw-r--r--pkg/packet/bgp/prefix_sid.go303
2 files changed, 306 insertions, 231 deletions
diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go
index 7adabe95..98408109 100644
--- a/pkg/packet/bgp/bgp.go
+++ b/pkg/packet/bgp/bgp.go
@@ -7833,237 +7833,6 @@ type PathAttributeLs struct {
TLVs []LsTLVInterface
}
-func (p *PathAttributeLs) Extract() *LsAttribute {
- l := &LsAttribute{}
-
- for _, tlv := range p.TLVs {
- switch v := tlv.(type) {
- case *LsTLVNodeFlagBits:
- l.Node.Flags = v.Extract()
-
- case *LsTLVOpaqueNodeAttr:
- l.Node.Opaque = &v.Attr
-
- case *LsTLVNodeName:
- l.Node.Name = &v.Name
-
- case *LsTLVIsisArea:
- l.Node.IsisArea = &v.Area
-
- case *LsTLVLocalIPv4RouterID:
- l.Node.LocalRouterID = &v.IP
- l.Link.LocalRouterID = &v.IP
-
- case *LsTLVLocalIPv6RouterID:
- l.Node.LocalRouterIDv6 = &v.IP
- l.Link.LocalRouterIDv6 = &v.IP
-
- case *LsTLVSrCapabilities:
- l.Node.SrCapabilties = v.Extract()
-
- case *LsTLVSrAlgorithm:
- l.Node.SrAlgorithms = &v.Algorithm
-
- case *LsTLVSrLocalBlock:
- l.Node.SrLocalBlock = v.Extract()
-
- case *LsTLVRemoteIPv4RouterID:
- l.Link.RemoteRouterID = &v.IP
-
- case *LsTLVRemoteIPv6RouterID:
- l.Link.RemoteRouterIDv6 = &v.IP
-
- case *LsTLVAdminGroup:
- l.Link.AdminGroup = &v.AdminGroup
-
- case *LsTLVMaxLinkBw:
- l.Link.Bandwidth = &v.Bandwidth
-
- case *LsTLVMaxReservableLinkBw:
- l.Link.ReservableBandwidth = &v.Bandwidth
-
- case *LsTLVUnreservedBw:
- l.Link.UnreservedBandwidth = &v.Bandwidth
-
- case *LsTLVSrlg:
- l.Link.Srlgs = &v.Srlgs
-
- case *LsTLVTEDefaultMetric:
- l.Link.DefaultTEMetric = &v.Metric
-
- case *LsTLVIGPMetric:
- l.Link.IGPMetric = &v.Metric
-
- case *LsTLVOpaqueLinkAttr:
- l.Link.Opaque = &v.Attr
-
- case *LsTLVLinkName:
- l.Link.Name = &v.Name
-
- case *LsTLVAdjacencySID:
- l.Link.SrAdjacencySID = &v.SID
-
- case *LsTLVIGPFlags:
- l.Prefix.IGPFlags = v.Extract()
-
- case *LsTLVOpaquePrefixAttr:
- l.Prefix.Opaque = &v.Attr
-
- case *LsTLVPrefixSID:
- l.Prefix.SrPrefixSID = &v.SID
- }
- }
-
- return l
-}
-
-func (p *PathAttributeLs) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
- tlvs, err := p.PathAttribute.DecodeFromBytes(data)
- if err != nil {
- return err
- }
-
- for len(tlvs) >= tlvHdrLen {
- t := &LsTLV{}
- _, err := t.DecodeFromBytes(tlvs)
- if err != nil {
- return err
- }
-
- var tlv LsTLVInterface
- switch t.Type {
- // Node NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.1)
- case LS_TLV_NODE_FLAG_BITS:
- tlv = &LsTLVNodeFlagBits{}
-
- case LS_TLV_OPAQUE_NODE_ATTR:
- tlv = &LsTLVOpaqueNodeAttr{}
-
- case LS_TLV_NODE_NAME:
- tlv = &LsTLVNodeName{}
-
- case LS_TLV_ISIS_AREA:
- tlv = &LsTLVIsisArea{}
-
- // Used by Link NLRI as well.
- case LS_TLV_IPV4_LOCAL_ROUTER_ID:
- tlv = &LsTLVLocalIPv4RouterID{}
-
- // Used by Link NLRI as well.
- case LS_TLV_IPV6_LOCAL_ROUTER_ID:
- tlv = &LsTLVLocalIPv6RouterID{}
-
- // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Node NLRI
- case LS_TLV_SR_CAPABILITIES:
- tlv = &LsTLVSrCapabilities{}
-
- case LS_TLV_SR_ALGORITHM:
- tlv = &LsTLVSrAlgorithm{}
-
- case LS_TLV_SR_LOCAL_BLOCK:
- tlv = &LsTLVSrLocalBlock{}
-
- // Link NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.2)
- case LS_TLV_IPV4_REMOTE_ROUTER_ID:
- tlv = &LsTLVRemoteIPv4RouterID{}
-
- case LS_TLV_IPV6_REMOTE_ROUTER_ID:
- tlv = &LsTLVRemoteIPv6RouterID{}
-
- case LS_TLV_ADMIN_GROUP:
- tlv = &LsTLVAdminGroup{}
-
- case LS_TLV_MAX_LINK_BANDWIDTH:
- tlv = &LsTLVMaxLinkBw{}
-
- case LS_TLV_MAX_RESERVABLE_BANDWIDTH:
- tlv = &LsTLVMaxReservableLinkBw{}
-
- case LS_TLV_UNRESERVED_BANDWIDTH:
- tlv = &LsTLVUnreservedBw{}
-
- case LS_TLV_SRLG:
- tlv = &LsTLVSrlg{}
-
- case LS_TLV_TE_DEFAULT_METRIC:
- tlv = &LsTLVTEDefaultMetric{}
-
- case LS_TLV_IGP_METRIC:
- tlv = &LsTLVIGPMetric{}
-
- case LS_TLV_OPAQUE_LINK_ATTR:
- tlv = &LsTLVOpaqueLinkAttr{}
-
- case LS_TLV_LINK_NAME:
- tlv = &LsTLVLinkName{}
-
- // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Link NLRI
- case LS_TLV_ADJACENCY_SID:
- tlv = &LsTLVAdjacencySID{}
-
- // Prefix NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.3)
- case LS_TLV_IGP_FLAGS:
- tlv = &LsTLVIGPFlags{}
-
- case LS_TLV_OPAQUE_PREFIX_ATTR:
- tlv = &LsTLVOpaquePrefixAttr{}
-
- // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Prefix NLRI
- case LS_TLV_PREFIX_SID:
- tlv = &LsTLVPrefixSID{}
-
- default:
- tlvs = tlvs[t.Len():]
- continue
- }
-
- if err := tlv.DecodeFromBytes(tlvs); err != nil {
- return err
- }
- tlvs = tlvs[t.Len():]
-
- p.TLVs = append(p.TLVs, tlv)
- }
-
- return nil
-}
-
-func (p *PathAttributeLs) Serialize(options ...*MarshallingOption) ([]byte, error) {
- buf := []byte{}
-
- for _, tlv := range p.TLVs {
- s, err := tlv.Serialize()
- if err != nil {
- return nil, err
- }
- buf = append(buf, s...)
- }
-
- return p.PathAttribute.Serialize(buf, options...)
-}
-
-func (p *PathAttributeLs) String() string {
- var buf bytes.Buffer
-
- for _, tlv := range p.TLVs {
- buf.WriteString(fmt.Sprintf("%s ", tlv.String()))
- }
-
- return fmt.Sprintf("{LsAttributes: %s}", buf.String())
-}
-
-func (p *PathAttributeLs) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type BGPAttrType `json:"type"`
- Flags BGPAttrFlag `json:"flags"`
- LsAttribute
- }{
- p.GetType(),
- p.GetFlags(),
- *p.Extract(),
- })
-}
-
func AfiSafiToRouteFamily(afi uint16, safi uint8) RouteFamily {
return RouteFamily(int(afi)<<16 | int(safi))
}
@@ -8285,6 +8054,7 @@ const (
_
BGP_ATTR_TYPE_LS // = 29
BGP_ATTR_TYPE_LARGE_COMMUNITY BGPAttrType = 32
+ BGP_ATTR_TYPE_PREFIX_SID = 40
)
// NOTIFICATION Error Code RFC 4271 4.5.
@@ -12373,6 +12143,8 @@ func GetPathAttribute(data []byte) (PathAttributeInterface, error) {
return &PathAttributeLargeCommunities{}, nil
case BGP_ATTR_TYPE_LS:
return &PathAttributeLs{}, nil
+ case BGP_ATTR_TYPE_PREFIX_SID:
+ return &PathAttributePrefixSID{}, nil
}
return &PathAttributeUnknown{}, nil
}
diff --git a/pkg/packet/bgp/prefix_sid.go b/pkg/packet/bgp/prefix_sid.go
new file mode 100644
index 00000000..4ae727f5
--- /dev/null
+++ b/pkg/packet/bgp/prefix_sid.go
@@ -0,0 +1,303 @@
+package bgp
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+)
+
+type PrefixSIDTLVType uint16
+
+type PrefixSIDTLV struct {
+ Type PrefixSIDTLVType
+ Length uint16
+}
+
+type PrefixSIDTLVInterface interface {
+ Len() int
+ DecodeFromBytes([]byte) error
+ Serialize() ([]byte, error)
+ String() string
+ MarshalJSON() ([]byte, error)
+}
+
+type PathAttributePrefixSID struct {
+ PathAttribute
+ TLVs []PrefixSIDTLVInterface
+}
+
+func (s *PrefixSIDTLV) Len() int {
+ return int(s.Length) + tlvHdrLen
+}
+
+func (s *PrefixSIDTLV) Serialize(value []byte) ([]byte, error) {
+ if len(value) != int(s.Length) {
+ return nil, malformedAttrListErr("serialization failed: Prefix SID TLV malformed")
+ }
+
+ buf := make([]byte, tlvHdrLen+len(value))
+ binary.BigEndian.PutUint16(buf[:2], uint16(s.Type))
+ binary.BigEndian.PutUint16(buf[2:4], uint16(s.Length))
+ copy(buf[4:], value)
+
+ return buf, nil
+}
+
+func (s *PrefixSIDTLV) DecodeFromBytes(data []byte) ([]byte, error) {
+ if len(data) < tlvHdrLen {
+ return nil, malformedAttrListErr("decoding failed: Prefix SID TLV malformed")
+ }
+ // l.Type = PrefixSIDTLVType(binary.BigEndian.Uint16(data[:2]))
+ // l.Length = binary.BigEndian.Uint16(data[2:4])
+
+ // if len(data) < l.Len() {
+ // return nil, malformedAttrListErr("decoding failed: Prefix SID TLV malformed")
+ // }
+
+ return data[tlvHdrLen:s.Len()], nil
+}
+
+//type LsAttributePrefix struct {
+// IGPFlags *LsIGPFlags `json:"igp_flags,omitempty"`
+// Opaque *[]byte `json:"opaque,omitempty"`
+//
+// SrPrefixSID *uint32 `json:"sr_prefix_sid,omitempty"`
+//}
+
+type PrefixSIDAttribute struct {
+ // Node LsAttributeNode `json:"node"`
+ // Link LsAttributeLink `json:"link"`
+ // Prefix LsAttributePrefix `json:"prefix"`
+}
+
+func (p *PathAttributePrefixSID) Extract() *PrefixSIDAttribute {
+ s := &PrefixSIDAttribute{}
+
+ // for _, tlv := range p.TLVs {
+ // switch v := tlv.(type) {
+ // case *LsTLVNodeFlagBits:
+ // l.Node.Flags = v.Extract()
+
+ // case *LsTLVOpaqueNodeAttr:
+ // l.Node.Opaque = &v.Attr
+
+ // case *LsTLVNodeName:
+ // l.Node.Name = &v.Name
+
+ // case *LsTLVIsisArea:
+ // l.Node.IsisArea = &v.Area
+
+ // case *LsTLVLocalIPv4RouterID:
+ // l.Node.LocalRouterID = &v.IP
+ // l.Link.LocalRouterID = &v.IP
+
+ // case *LsTLVLocalIPv6RouterID:
+ // l.Node.LocalRouterIDv6 = &v.IP
+ // l.Link.LocalRouterIDv6 = &v.IP
+
+ // case *LsTLVSrCapabilities:
+ // l.Node.SrCapabilties = v.Extract()
+
+ // case *LsTLVSrAlgorithm:
+ // l.Node.SrAlgorithms = &v.Algorithm
+
+ // case *LsTLVSrLocalBlock:
+ // l.Node.SrLocalBlock = v.Extract()
+
+ // case *LsTLVRemoteIPv4RouterID:
+ // l.Link.RemoteRouterID = &v.IP
+
+ // case *LsTLVRemoteIPv6RouterID:
+ // l.Link.RemoteRouterIDv6 = &v.IP
+
+ // case *LsTLVAdminGroup:
+ // l.Link.AdminGroup = &v.AdminGroup
+
+ // case *LsTLVMaxLinkBw:
+ // l.Link.Bandwidth = &v.Bandwidth
+
+ // case *LsTLVMaxReservableLinkBw:
+ // l.Link.ReservableBandwidth = &v.Bandwidth
+
+ // case *LsTLVUnreservedBw:
+ // l.Link.UnreservedBandwidth = &v.Bandwidth
+
+ // case *LsTLVSrlg:
+ // l.Link.Srlgs = &v.Srlgs
+
+ // case *LsTLVTEDefaultMetric:
+ // l.Link.DefaultTEMetric = &v.Metric
+
+ // case *LsTLVIGPMetric:
+ // l.Link.IGPMetric = &v.Metric
+
+ // case *LsTLVOpaqueLinkAttr:
+ // l.Link.Opaque = &v.Attr
+
+ // case *LsTLVLinkName:
+ // l.Link.Name = &v.Name
+
+ // case *LsTLVAdjacencySID:
+ // l.Link.SrAdjacencySID = &v.SID
+
+ // case *LsTLVIGPFlags:
+ // l.Prefix.IGPFlags = v.Extract()
+
+ // case *LsTLVOpaquePrefixAttr:
+ // l.Prefix.Opaque = &v.Attr
+
+ // case *LsTLVPrefixSID:
+ // l.Prefix.SrPrefixSID = &v.SID
+ // }
+ // }
+
+ return s
+}
+
+func (p *PathAttributePrefixSID) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
+ tlvs, err := p.PathAttribute.DecodeFromBytes(data)
+ if err != nil {
+ return err
+ }
+
+ for len(tlvs) >= tlvHdrLen {
+ t := &PrefixSIDTLV{}
+ _, err := t.DecodeFromBytes(tlvs)
+ if err != nil {
+ return err
+ }
+
+ var tlv PrefixSIDTLVInterface
+ // switch t.Type {
+ // // Node NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.1)
+ // case LS_TLV_NODE_FLAG_BITS:
+ // tlv = &LsTLVNodeFlagBits{}
+
+ // case LS_TLV_OPAQUE_NODE_ATTR:
+ // tlv = &LsTLVOpaqueNodeAttr{}
+
+ // case LS_TLV_NODE_NAME:
+ // tlv = &LsTLVNodeName{}
+
+ // case LS_TLV_ISIS_AREA:
+ // tlv = &LsTLVIsisArea{}
+
+ // // Used by Link NLRI as well.
+ // case LS_TLV_IPV4_LOCAL_ROUTER_ID:
+ // tlv = &LsTLVLocalIPv4RouterID{}
+
+ // // Used by Link NLRI as well.
+ // case LS_TLV_IPV6_LOCAL_ROUTER_ID:
+ // tlv = &LsTLVLocalIPv6RouterID{}
+
+ // // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Node NLRI
+ // case LS_TLV_SR_CAPABILITIES:
+ // tlv = &LsTLVSrCapabilities{}
+
+ // case LS_TLV_SR_ALGORITHM:
+ // tlv = &LsTLVSrAlgorithm{}
+
+ // case LS_TLV_SR_LOCAL_BLOCK:
+ // tlv = &LsTLVSrLocalBlock{}
+
+ // // Link NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.2)
+ // case LS_TLV_IPV4_REMOTE_ROUTER_ID:
+ // tlv = &LsTLVRemoteIPv4RouterID{}
+
+ // case LS_TLV_IPV6_REMOTE_ROUTER_ID:
+ // tlv = &LsTLVRemoteIPv6RouterID{}
+
+ // case LS_TLV_ADMIN_GROUP:
+ // tlv = &LsTLVAdminGroup{}
+
+ // case LS_TLV_MAX_LINK_BANDWIDTH:
+ // tlv = &LsTLVMaxLinkBw{}
+
+ // case LS_TLV_MAX_RESERVABLE_BANDWIDTH:
+ // tlv = &LsTLVMaxReservableLinkBw{}
+
+ // case LS_TLV_UNRESERVED_BANDWIDTH:
+ // tlv = &LsTLVUnreservedBw{}
+
+ // case LS_TLV_SRLG:
+ // tlv = &LsTLVSrlg{}
+
+ // case LS_TLV_TE_DEFAULT_METRIC:
+ // tlv = &LsTLVTEDefaultMetric{}
+
+ // case LS_TLV_IGP_METRIC:
+ // tlv = &LsTLVIGPMetric{}
+
+ // case LS_TLV_OPAQUE_LINK_ATTR:
+ // tlv = &LsTLVOpaqueLinkAttr{}
+
+ // case LS_TLV_LINK_NAME:
+ // tlv = &LsTLVLinkName{}
+
+ // // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Link NLRI
+ // case LS_TLV_ADJACENCY_SID:
+ // tlv = &LsTLVAdjacencySID{}
+
+ // // Prefix NLRI-related TLVs (https://tools.ietf.org/html/rfc7752#section-3.3.3)
+ // case LS_TLV_IGP_FLAGS:
+ // tlv = &LsTLVIGPFlags{}
+
+ // case LS_TLV_OPAQUE_PREFIX_ATTR:
+ // tlv = &LsTLVOpaquePrefixAttr{}
+
+ // // SR-related TLVs (draft-ietf-idr-bgp-ls-segment-routing-ext-08) for Prefix NLRI
+ // case LS_TLV_PREFIX_SID:
+ // tlv = &LsTLVPrefixSID{}
+
+ // default:
+ // tlvs = tlvs[t.Len():]
+ // continue
+ // }
+
+ if err := tlv.DecodeFromBytes(tlvs); err != nil {
+ return err
+ }
+ tlvs = tlvs[t.Len():]
+
+ p.TLVs = append(p.TLVs, tlv)
+ }
+
+ return nil
+}
+
+func (p *PathAttributePrefixSID) Serialize(options ...*MarshallingOption) ([]byte, error) {
+ buf := []byte{}
+
+ for _, tlv := range p.TLVs {
+ s, err := tlv.Serialize()
+ if err != nil {
+ return nil, err
+ }
+ buf = append(buf, s...)
+ }
+
+ return p.PathAttribute.Serialize(buf, options...)
+}
+
+func (p *PathAttributePrefixSID) String() string {
+ var buf bytes.Buffer
+
+ for _, tlv := range p.TLVs {
+ buf.WriteString(fmt.Sprintf("%s ", tlv.String()))
+ }
+
+ return fmt.Sprintf("{LsAttributes: %s}", buf.String())
+}
+
+func (p *PathAttributePrefixSID) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type BGPAttrType `json:"type"`
+ Flags BGPAttrFlag `json:"flags"`
+ PrefixSIDAttribute
+ }{
+ p.GetType(),
+ p.GetFlags(),
+ *p.Extract(),
+ })
+}