summaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/apiutil/attribute.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/apiutil/attribute.go')
-rw-r--r--internal/pkg/apiutil/attribute.go128
1 files changed, 124 insertions, 4 deletions
diff --git a/internal/pkg/apiutil/attribute.go b/internal/pkg/apiutil/attribute.go
index 112df6ff..a85ec06b 100644
--- a/internal/pkg/apiutil/attribute.go
+++ b/internal/pkg/apiutil/attribute.go
@@ -1167,6 +1167,9 @@ func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.Tun
Type: uint32(sv.Type),
Value: sv.Value,
}
+
+ // TODO (sbezverk) Add processing new tunneling sub tlvs
+
}
an, _ := ptypes.MarshalAny(subTlv)
subTlvs = append(subTlvs, an)
@@ -1611,15 +1614,58 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol))
case *api.TunnelEncapSubTLVColor:
subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color)
-
- // TODO (sbezverk) Add processing SR Policy Tunnel sub tlv
case *api.TunnelEncapSubTLVSRPreference:
subTlv = bgp.NewTunnelEncapSubTLVSRPreference(sv.Flags, sv.Preference)
-
+ case *api.TunnelEncapSubTLVSRPriority:
+ subTlv = bgp.NewTunnelEncapSubTLVSRPriority(uint8(sv.Priority))
+ case *api.TunnelEncapSubTLVSRCandidatePathName:
+ subTlv = bgp.NewTunnelEncapSubTLVSRCandidatePathName(sv.CandidatePathName)
+ case *api.TunnelEncapSubTLVSRENLP:
+ subTlv = bgp.NewTunnelEncapSubTLVSRENLP(sv.Flags, bgp.SRENLPValue(sv.Enlp))
+ case *api.TunnelEncapSubTLVSRBindingSID:
+ var err error
+ subTlv, err = UnmarshalSRBSID(sv.Bsid)
+ if err != nil {
+ return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
+ }
+ case *api.TunnelEncapSubTLVSRSegmentList:
+ var err error
+ weight := uint32(0)
+ flags := uint8(0)
+ if sv.Weight != nil {
+ weight = sv.Weight.Weight
+ flags = uint8(sv.Weight.Flags)
+ }
+ s := &bgp.TunnelEncapSubTLVSRSegmentList{
+ TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
+ Type: bgp.ENCAP_SUBTLV_TYPE_SRSEGMENT_LIST,
+ Length: uint16(6), // Weight (6 bytes) + length of segment (added later, after all segments are discovered)
+ },
+ Weight: &bgp.SegmentListWeight{
+ TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
+ Type: bgp.SegmentListSubTLVWeight,
+ Length: uint16(6),
+ },
+ Flags: flags,
+ Weight: weight,
+ },
+ Segments: make([]bgp.TunnelEncapSubTLVInterface, 0),
+ }
+ if len(sv.Segments) != 0 {
+ s.Segments, err = UnmarshalSRSegments(sv.Segments)
+ if err != nil {
+ return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
+ }
+ }
+ // Get total length of Segment List Sub TLV
+ for _, seg := range s.Segments {
+ s.TunnelEncapSubTLV.Length += uint16(seg.Len() + 2) // Adding 1 byte of type and 1 byte of length for each Segment object
+ }
+ subTlv = s
case *api.TunnelEncapSubTLVUnknown:
subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value)
default:
- return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message)
+ return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v type: %T", subValue.Message, sv)
}
subTlvs = append(subTlvs, subTlv)
}
@@ -1681,3 +1727,77 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
}
return nil, errors.New("unknown path attribute")
}
+
+// UnmarshalSRBSID unmarshals SR Policy Binding SID Sub TLV and returns native TunnelEncapSubTLVInterface interface
+func UnmarshalSRBSID(bsid *any.Any) (bgp.TunnelEncapSubTLVInterface, error) {
+ var value ptypes.DynamicAny
+ if err := ptypes.UnmarshalAny(bsid, &value); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal tunnel encap sub tlv: %s", err)
+ }
+ switch v := value.Message.(type) {
+ case *api.SRBindingSID:
+ b, err := bgp.NewBSID(v.Sid)
+ if err != nil {
+ return nil, err
+ }
+ flags := uint8(0x0)
+ if v.SFlag {
+ flags += 0x80
+ }
+ if v.IFlag {
+ flags += 0x40
+ }
+ return &bgp.TunnelEncapSubTLVSRBSID{
+ TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
+ Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID,
+ Length: uint16(2 + b.Len()),
+ },
+ BSID: b,
+ Flags: flags,
+ }, nil
+ case *api.SRv6BindingSID:
+ return nil, fmt.Errorf("srv6 binding sid is not yet supported")
+ default:
+ return nil, fmt.Errorf("unknown binding sid type %+v", v)
+ }
+}
+
+// UnmarshalSRSegments unmarshals SR Policy Segments slice of structs
+func UnmarshalSRSegments(s []*any.Any) ([]bgp.TunnelEncapSubTLVInterface, error) {
+ if len(s) == 0 {
+ return nil, nil
+ }
+ segments := make([]bgp.TunnelEncapSubTLVInterface, len(s))
+ for i := 0; i < len(s); i++ {
+ var value ptypes.DynamicAny
+ if err := ptypes.UnmarshalAny(s[i], &value); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal SR Policy Segment: %s", err)
+ }
+ switch v := value.Message.(type) {
+ case *api.SegmentTypeA:
+ seg := &bgp.SegmentTypeA{
+ TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
+ Type: bgp.EncapSubTLVType(bgp.TypeA),
+ Length: 6,
+ },
+ Label: v.Label << 12,
+ }
+ if v.Flags.VFlag {
+ seg.Flags += 0x80
+ }
+ if v.Flags.AFlag {
+ seg.Flags += 0x40
+ }
+ if v.Flags.SFlag {
+ seg.Flags += 0x20
+ }
+ if v.Flags.BFlag {
+ seg.Flags += 0x10
+ }
+ segments[i] = seg
+ case *api.SegmentTypeB:
+ return nil, fmt.Errorf("segment of type B is not yet supported")
+ }
+ }
+ return segments, nil
+}