summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorSerguei Bezverkhi <sbezverk@cisco.com>2020-05-05 14:31:28 -0400
committerSerguei Bezverkhi <sbezverk@cisco.com>2020-05-05 14:31:28 -0400
commit8409507a7c4888714df987e368de6bffc2fdf8ba (patch)
tree50b57e1bd3d3233e78d8c74f0ac9201d39835dc2 /pkg
parentf11ece918f233e62a98c0d40b4ec3a90417aa3a6 (diff)
coding the feature
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/packet/bgp/bgp.go234
1 files changed, 234 insertions, 0 deletions
diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go
index 98408109..20d210ab 100644
--- a/pkg/packet/bgp/bgp.go
+++ b/pkg/packet/bgp/bgp.go
@@ -28,6 +28,8 @@ import (
"sort"
"strconv"
"strings"
+
+ "github.com/golang/glog"
)
type MarshallingOption struct {
@@ -7833,6 +7835,237 @@ 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))
}
@@ -12144,6 +12377,7 @@ func GetPathAttribute(data []byte) (PathAttributeInterface, error) {
case BGP_ATTR_TYPE_LS:
return &PathAttributeLs{}, nil
case BGP_ATTR_TYPE_PREFIX_SID:
+ glog.Infof("><SB> BGP Prefix SI attribute detected: %+v", data)
return &PathAttributePrefixSID{}, nil
}
return &PathAttributeUnknown{}, nil