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.go113
1 files changed, 112 insertions, 1 deletions
diff --git a/internal/pkg/apiutil/attribute.go b/internal/pkg/apiutil/attribute.go
index 1610a181..8422f3f3 100644
--- a/internal/pkg/apiutil/attribute.go
+++ b/internal/pkg/apiutil/attribute.go
@@ -75,6 +75,8 @@ func UnmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
}
}
return bgp.NewPathAttributeClusterList(a.Ids), nil
+ case *api.PrefixSID:
+ return bgp.NewPathAttributePrefixSID(a)
}
return nil, errors.New("unexpected object")
}
@@ -149,6 +151,114 @@ func NewClusterListAttributeFromNative(a *bgp.PathAttributeClusterList) *api.Clu
}
}
+func NewPrefixSIDAttributeFromNative(a *bgp.PathAttributePrefixSID) *api.PrefixSID {
+ psid := &api.PrefixSID{}
+ psid.Tlvs = MarshalSRv6TLVs(a.TLVs)
+
+ return psid
+}
+
+func MarshalSRv6TLVs(tlvs []bgp.PrefixSIDTLVInterface) []*any.Any {
+ mtlvs := make([]*any.Any, len(tlvs))
+ for i, tlv := range tlvs {
+ var r proto.Message
+ switch t := tlv.(type) {
+ case *bgp.SRv6L3ServiceAttribute:
+ o := &api.SRv6L3ServiceTLV{}
+ o.SubTlvs = MarshalSRv6SubTLVs(t.SubTLVs)
+ r = o
+ default:
+ log.WithFields(log.Fields{
+ "Topic": "protobuf",
+ "SRv6": t,
+ }).Warn("invalid prefix sid tlv type to marshal")
+ return nil
+ }
+ a, _ := ptypes.MarshalAny(r)
+ mtlvs[i] = a
+ }
+
+ return mtlvs
+}
+
+func MarshalSRv6SubTLVs(tlvs []bgp.PrefixSIDTLVInterface) map[uint32]*api.SRv6TLV {
+ mtlvs := make(map[uint32]*api.SRv6TLV)
+ var key uint32
+ for _, tlv := range tlvs {
+ var r proto.Message
+ switch t := tlv.(type) {
+ case *bgp.SRv6InformationSubTLV:
+ o := &api.SRv6InformationSubTLV{
+ EndpointBehavior: uint32(t.EndpointBehavior),
+ // TODO Once flags are used in RFC, add processing.
+ Flags: &api.SRv6SIDFlags{},
+ }
+ o.Sid = make([]byte, len(t.SID))
+ copy(o.Sid, t.SID)
+ o.SubSubTlvs = MarshalSRv6SubSubTLVs(t.SubSubTLVs)
+ // SRv6 Information Sub TLV is type 1 Sub TLV
+ key = 1
+ r = o
+ default:
+ log.WithFields(log.Fields{
+ "Topic": "protobuf",
+ "SRv6": t,
+ }).Warn("invalid prefix sid sub tlv type to marshal")
+ return nil
+ }
+ a, _ := ptypes.MarshalAny(r)
+ tlvs, ok := mtlvs[key]
+ if !ok {
+ tlvs = &api.SRv6TLV{
+ Tlv: make([]*any.Any, 0),
+ }
+ mtlvs[key] = tlvs
+ }
+ tlvs.Tlv = append(tlvs.Tlv, a)
+ }
+
+ return mtlvs
+}
+
+func MarshalSRv6SubSubTLVs(tlvs []bgp.PrefixSIDTLVInterface) map[uint32]*api.SRv6TLV {
+ mtlvs := make(map[uint32]*api.SRv6TLV)
+ var key uint32
+ for _, tlv := range tlvs {
+ var r proto.Message
+ switch t := tlv.(type) {
+ case *bgp.SRv6SIDStructureSubSubTLV:
+ o := &api.SRv6StructureSubSubTLV{
+ LocalBlockLength: uint32(t.LocalBlockLength),
+ LocalNodeLength: uint32(t.LocatorNodeLength),
+ FunctionLength: uint32(t.FunctionLength),
+ ArgumentLength: uint32(t.ArgumentLength),
+ TranspositionLength: uint32(t.TranspositionLength),
+ TranspositionOffset: uint32(t.TranspositionOffset),
+ }
+ // SRv6 SID Structure Sub Sub TLV is type 1 Sub Sub TLV
+ key = 1
+ r = o
+ default:
+ log.WithFields(log.Fields{
+ "Topic": "protobuf",
+ "SRv6": t,
+ }).Warn("invalid prefix sid sub sub tlv type to marshal")
+ return nil
+ }
+ a, _ := ptypes.MarshalAny(r)
+ tlvs, ok := mtlvs[key]
+ if !ok {
+ tlvs = &api.SRv6TLV{
+ Tlv: make([]*any.Any, 0),
+ }
+ mtlvs[key] = tlvs
+ }
+ tlvs.Tlv = append(tlvs.Tlv, a)
+ }
+
+ return mtlvs
+}
+
func MarshalRD(rd bgp.RouteDistinguisherInterface) *any.Any {
var r proto.Message
switch v := rd.(type) {
@@ -1537,7 +1647,8 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
communities = append(communities, bgp.NewLargeCommunity(c.GlobalAdmin, c.LocalData1, c.LocalData2))
}
return bgp.NewPathAttributeLargeCommunities(communities), nil
-
+ case *api.PrefixSID:
+ return bgp.NewPathAttributePrefixSID(a)
case *api.UnknownAttribute:
return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil
}