github.com/osrg/gobgp/v3@v3.30.0/pkg/apiutil/attribute.go (about) 1 // Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package apiutil 17 18 import ( 19 "encoding/binary" 20 "errors" 21 "fmt" 22 "net" 23 "net/netip" 24 25 "google.golang.org/protobuf/proto" 26 apb "google.golang.org/protobuf/types/known/anypb" 27 28 api "github.com/osrg/gobgp/v3/api" 29 "github.com/osrg/gobgp/v3/pkg/packet/bgp" 30 ) 31 32 func UnmarshalAttribute(an *apb.Any) (bgp.PathAttributeInterface, error) { 33 value, err := an.UnmarshalNew() 34 if err != nil { 35 return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) 36 } 37 switch a := value.(type) { 38 case *api.OriginAttribute: 39 return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil 40 case *api.AsPathAttribute: 41 params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) 42 for _, segment := range a.Segments { 43 params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) 44 } 45 return bgp.NewPathAttributeAsPath(params), nil 46 case *api.NextHopAttribute: 47 nexthop := net.ParseIP(a.NextHop).To4() 48 if nexthop == nil { 49 if nexthop = net.ParseIP(a.NextHop).To16(); nexthop == nil { 50 return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) 51 } 52 } 53 return bgp.NewPathAttributeNextHop(a.NextHop), nil 54 case *api.MultiExitDiscAttribute: 55 return bgp.NewPathAttributeMultiExitDisc(a.Med), nil 56 case *api.LocalPrefAttribute: 57 return bgp.NewPathAttributeLocalPref(a.LocalPref), nil 58 case *api.AtomicAggregateAttribute: 59 return bgp.NewPathAttributeAtomicAggregate(), nil 60 case *api.AggregatorAttribute: 61 if net.ParseIP(a.Address).To4() == nil { 62 return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) 63 } 64 return bgp.NewPathAttributeAggregator(a.Asn, a.Address), nil 65 case *api.CommunitiesAttribute: 66 return bgp.NewPathAttributeCommunities(a.Communities), nil 67 case *api.OriginatorIdAttribute: 68 if net.ParseIP(a.Id).To4() == nil { 69 return nil, fmt.Errorf("invalid originator id: %s", a.Id) 70 } 71 return bgp.NewPathAttributeOriginatorId(a.Id), nil 72 case *api.ClusterListAttribute: 73 for _, id := range a.Ids { 74 if net.ParseIP(id).To4() == nil { 75 return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) 76 } 77 } 78 return bgp.NewPathAttributeClusterList(a.Ids), nil 79 case *api.MpReachNLRIAttribute: 80 if a.Family == nil { 81 return nil, fmt.Errorf("empty family") 82 } 83 rf := ToRouteFamily(a.Family) 84 nlris, err := UnmarshalNLRIs(rf, a.Nlris) 85 if err != nil { 86 return nil, err 87 } 88 afi, safi := bgp.RouteFamilyToAfiSafi(rf) 89 nexthop := "0.0.0.0" 90 var linkLocalNexthop net.IP 91 if afi == bgp.AFI_IP6 { 92 nexthop = "::" 93 if len(a.NextHops) > 1 { 94 linkLocalNexthop = net.ParseIP(a.NextHops[1]).To16() 95 if linkLocalNexthop == nil { 96 return nil, fmt.Errorf("invalid nexthop: %s", a.NextHops[1]) 97 } 98 } 99 } 100 if safi == bgp.SAFI_FLOW_SPEC_UNICAST || safi == bgp.SAFI_FLOW_SPEC_VPN { 101 nexthop = "" 102 } else if len(a.NextHops) > 0 { 103 nexthop = a.NextHops[0] 104 if net.ParseIP(nexthop) == nil { 105 return nil, fmt.Errorf("invalid nexthop: %s", nexthop) 106 } 107 } 108 attr := bgp.NewPathAttributeMpReachNLRI(nexthop, nlris) 109 attr.LinkLocalNexthop = linkLocalNexthop 110 return attr, nil 111 case *api.MpUnreachNLRIAttribute: 112 rf := ToRouteFamily(a.Family) 113 nlris, err := UnmarshalNLRIs(rf, a.Nlris) 114 if err != nil { 115 return nil, err 116 } 117 return bgp.NewPathAttributeMpUnreachNLRI(nlris), nil 118 case *api.ExtendedCommunitiesAttribute: 119 return unmarshalExComm(a) 120 case *api.As4PathAttribute: 121 params := make([]*bgp.As4PathParam, 0, len(a.Segments)) 122 for _, segment := range a.Segments { 123 params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) 124 } 125 return bgp.NewPathAttributeAs4Path(params), nil 126 case *api.As4AggregatorAttribute: 127 if net.ParseIP(a.Address).To4() == nil { 128 return nil, fmt.Errorf("invalid as4 aggregator address: %s", a.Address) 129 } 130 return bgp.NewPathAttributeAs4Aggregator(a.Asn, a.Address), nil 131 case *api.PmsiTunnelAttribute: 132 typ := bgp.PmsiTunnelType(a.Type) 133 var isLeafInfoRequired bool 134 if a.Flags&0x01 > 0 { 135 isLeafInfoRequired = true 136 } 137 var id bgp.PmsiTunnelIDInterface 138 switch typ { 139 case bgp.PMSI_TUNNEL_TYPE_INGRESS_REPL: 140 ip := net.IP(a.Id) 141 if ip.To4() == nil && ip.To16() == nil { 142 return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", a.Id) 143 } 144 id = bgp.NewIngressReplTunnelID(ip.String()) 145 default: 146 id = bgp.NewDefaultPmsiTunnelID(a.Id) 147 } 148 return bgp.NewPathAttributePmsiTunnel(typ, isLeafInfoRequired, a.Label, id), nil 149 case *api.TunnelEncapAttribute: 150 tlvs := make([]*bgp.TunnelEncapTLV, 0, len(a.Tlvs)) 151 for _, tlv := range a.Tlvs { 152 subTlvs := make([]bgp.TunnelEncapSubTLVInterface, 0, len(tlv.Tlvs)) 153 for _, an := range tlv.Tlvs { 154 var subTlv bgp.TunnelEncapSubTLVInterface 155 subValue, err := an.UnmarshalNew() 156 if err != nil { 157 return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) 158 } 159 switch sv := subValue.(type) { 160 case *api.TunnelEncapSubTLVEncapsulation: 161 subTlv = bgp.NewTunnelEncapSubTLVEncapsulation(sv.Key, sv.Cookie) 162 case *api.TunnelEncapSubTLVProtocol: 163 subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol)) 164 case *api.TunnelEncapSubTLVColor: 165 subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color) 166 case *api.TunnelEncapSubTLVEgressEndpoint: 167 subTlv = bgp.NewTunnelEncapSubTLVEgressEndpoint(sv.Address) 168 case *api.TunnelEncapSubTLVUDPDestPort: 169 subTlv = bgp.NewTunnelEncapSubTLVUDPDestPort(uint16(sv.Port)) 170 case *api.TunnelEncapSubTLVSRPreference: 171 subTlv = bgp.NewTunnelEncapSubTLVSRPreference(sv.Flags, sv.Preference) 172 case *api.TunnelEncapSubTLVSRPriority: 173 subTlv = bgp.NewTunnelEncapSubTLVSRPriority(uint8(sv.Priority)) 174 case *api.TunnelEncapSubTLVSRCandidatePathName: 175 subTlv = bgp.NewTunnelEncapSubTLVSRCandidatePathName(sv.CandidatePathName) 176 case *api.TunnelEncapSubTLVSRENLP: 177 subTlv = bgp.NewTunnelEncapSubTLVSRENLP(sv.Flags, bgp.SRENLPValue(sv.Enlp)) 178 case *api.TunnelEncapSubTLVSRBindingSID: 179 var err error 180 subTlv, err = UnmarshalSRBSID(sv.Bsid) 181 if err != nil { 182 return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) 183 } 184 case *api.TunnelEncapSubTLVSRSegmentList: 185 var err error 186 weight := uint32(0) 187 flags := uint8(0) 188 if sv.Weight != nil { 189 weight = sv.Weight.Weight 190 flags = uint8(sv.Weight.Flags) 191 } 192 s := &bgp.TunnelEncapSubTLVSRSegmentList{ 193 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 194 Type: bgp.ENCAP_SUBTLV_TYPE_SRSEGMENT_LIST, 195 Length: uint16(6), // Weight (6 bytes) + length of segment (added later, after all segments are discovered) 196 }, 197 Weight: &bgp.SegmentListWeight{ 198 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 199 Type: bgp.SegmentListSubTLVWeight, 200 Length: uint16(6), 201 }, 202 Flags: flags, 203 Weight: weight, 204 }, 205 Segments: make([]bgp.TunnelEncapSubTLVInterface, 0), 206 } 207 if len(sv.Segments) != 0 { 208 s.Segments, err = UnmarshalSRSegments(sv.Segments) 209 if err != nil { 210 return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) 211 } 212 } 213 // Get total length of Segment List Sub TLV 214 for _, seg := range s.Segments { 215 s.TunnelEncapSubTLV.Length += uint16(seg.Len() + 2) // Adding 1 byte of type and 1 byte of length for each Segment object 216 } 217 subTlv = s 218 case *api.TunnelEncapSubTLVUnknown: 219 subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value) 220 default: 221 return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v type: %T", subValue, sv) 222 } 223 subTlvs = append(subTlvs, subTlv) 224 } 225 tlvs = append(tlvs, bgp.NewTunnelEncapTLV(bgp.TunnelType(tlv.Type), subTlvs)) 226 } 227 return bgp.NewPathAttributeTunnelEncap(tlvs), nil 228 case *api.IP6ExtendedCommunitiesAttribute: 229 communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) 230 for _, an := range a.Communities { 231 var community bgp.ExtendedCommunityInterface 232 value, err := an.UnmarshalNew() 233 if err != nil { 234 return nil, fmt.Errorf("failed to unmarshal ipv6 extended community: %s", err) 235 } 236 switch v := value.(type) { 237 case *api.IPv6AddressSpecificExtended: 238 community = bgp.NewIPv6AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 239 case *api.RedirectIPv6AddressSpecificExtended: 240 community = bgp.NewRedirectIPv6AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) 241 } 242 if community == nil { 243 return nil, fmt.Errorf("invalid ipv6 extended community: %v", value) 244 } 245 communities = append(communities, community) 246 } 247 return bgp.NewPathAttributeIP6ExtendedCommunities(communities), nil 248 249 case *api.AigpAttribute: 250 tlvs := make([]bgp.AigpTLVInterface, 0, len(a.Tlvs)) 251 for _, an := range a.Tlvs { 252 var tlv bgp.AigpTLVInterface 253 value, err := an.UnmarshalNew() 254 if err != nil { 255 return nil, fmt.Errorf("failed to unmarshal aigp attribute tlv: %s", err) 256 } 257 switch v := value.(type) { 258 case *api.AigpTLVIGPMetric: 259 tlv = bgp.NewAigpTLVIgpMetric(v.Metric) 260 case *api.AigpTLVUnknown: 261 tlv = bgp.NewAigpTLVDefault(bgp.AigpTLVType(v.Type), v.Value) 262 } 263 if tlv == nil { 264 return nil, fmt.Errorf("invalid aigp attribute tlv: %v", value) 265 } 266 tlvs = append(tlvs, tlv) 267 } 268 return bgp.NewPathAttributeAigp(tlvs), nil 269 270 case *api.LargeCommunitiesAttribute: 271 communities := make([]*bgp.LargeCommunity, 0, len(a.Communities)) 272 for _, c := range a.Communities { 273 communities = append(communities, bgp.NewLargeCommunity(c.GlobalAdmin, c.LocalData1, c.LocalData2)) 274 } 275 return bgp.NewPathAttributeLargeCommunities(communities), nil 276 case *api.PrefixSID: 277 return UnmarshalPrefixSID(a) 278 case *api.LsAttribute: 279 lsAttr, err := UnmarshalLsAttribute(a) 280 if err != nil { 281 return nil, fmt.Errorf("failed to unmarshal BGP-LS Attribute: %s", err) 282 } 283 tlvs := bgp.NewLsAttributeTLVs(lsAttr) 284 var length uint16 285 for _, tlv := range tlvs { 286 length += uint16(tlv.Len()) 287 } 288 t := bgp.BGP_ATTR_TYPE_LS 289 pathAttributeLs := &bgp.PathAttributeLs{ 290 PathAttribute: bgp.PathAttribute{ 291 Flags: bgp.PathAttrFlags[t], 292 Type: t, 293 Length: length, 294 }, 295 TLVs: tlvs, 296 } 297 298 return pathAttributeLs, nil 299 300 case *api.UnknownAttribute: 301 return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil 302 } 303 return nil, errors.New("unknown path attribute") 304 } 305 306 func NewOriginAttributeFromNative(a *bgp.PathAttributeOrigin) (*api.OriginAttribute, error) { 307 return &api.OriginAttribute{ 308 Origin: uint32(a.Value), 309 }, nil 310 } 311 312 func NewAsPathAttributeFromNative(a *bgp.PathAttributeAsPath) (*api.AsPathAttribute, error) { 313 segments := make([]*api.AsSegment, 0, len(a.Value)) 314 for _, param := range a.Value { 315 segments = append(segments, &api.AsSegment{ 316 Type: api.AsSegment_Type(param.GetType()), 317 Numbers: param.GetAS(), 318 }) 319 } 320 return &api.AsPathAttribute{ 321 Segments: segments, 322 }, nil 323 } 324 325 func NewNextHopAttributeFromNative(a *bgp.PathAttributeNextHop) (*api.NextHopAttribute, error) { 326 return &api.NextHopAttribute{ 327 NextHop: a.Value.String(), 328 }, nil 329 } 330 331 func NewMultiExitDiscAttributeFromNative(a *bgp.PathAttributeMultiExitDisc) (*api.MultiExitDiscAttribute, error) { 332 return &api.MultiExitDiscAttribute{ 333 Med: a.Value, 334 }, nil 335 } 336 337 func NewLocalPrefAttributeFromNative(a *bgp.PathAttributeLocalPref) (*api.LocalPrefAttribute, error) { 338 return &api.LocalPrefAttribute{ 339 LocalPref: a.Value, 340 }, nil 341 } 342 343 func NewAtomicAggregateAttributeFromNative(a *bgp.PathAttributeAtomicAggregate) (*api.AtomicAggregateAttribute, error) { 344 return &api.AtomicAggregateAttribute{}, nil 345 } 346 347 func NewAggregatorAttributeFromNative(a *bgp.PathAttributeAggregator) (*api.AggregatorAttribute, error) { 348 return &api.AggregatorAttribute{ 349 Asn: a.Value.AS, 350 Address: a.Value.Address.String(), 351 }, nil 352 } 353 354 func NewCommunitiesAttributeFromNative(a *bgp.PathAttributeCommunities) (*api.CommunitiesAttribute, error) { 355 return &api.CommunitiesAttribute{ 356 Communities: a.Value, 357 }, nil 358 } 359 360 func NewOriginatorIdAttributeFromNative(a *bgp.PathAttributeOriginatorId) (*api.OriginatorIdAttribute, error) { 361 return &api.OriginatorIdAttribute{ 362 Id: a.Value.String(), 363 }, nil 364 } 365 366 func NewClusterListAttributeFromNative(a *bgp.PathAttributeClusterList) (*api.ClusterListAttribute, error) { 367 ids := make([]string, 0, len(a.Value)) 368 for _, id := range a.Value { 369 ids = append(ids, id.String()) 370 } 371 return &api.ClusterListAttribute{ 372 Ids: ids, 373 }, nil 374 } 375 376 func NewPrefixSIDAttributeFromNative(a *bgp.PathAttributePrefixSID) (*api.PrefixSID, error) { 377 var err error 378 psid := &api.PrefixSID{} 379 psid.Tlvs, err = MarshalSRv6TLVs(a.TLVs) 380 if err != nil { 381 return nil, err 382 } 383 return psid, nil 384 } 385 386 func MarshalSRv6TLVs(tlvs []bgp.PrefixSIDTLVInterface) ([]*apb.Any, error) { 387 var err error 388 mtlvs := make([]*apb.Any, len(tlvs)) 389 for i, tlv := range tlvs { 390 var r proto.Message 391 switch t := tlv.(type) { 392 case *bgp.SRv6L3ServiceAttribute: 393 o := &api.SRv6L3ServiceTLV{} 394 o.SubTlvs, err = MarshalSRv6SubTLVs(t.SubTLVs) 395 if err != nil { 396 return nil, err 397 } 398 r = o 399 case *bgp.SRv6ServiceTLV: 400 switch t.TLV.Type { 401 case bgp.TLVTypeSRv6L3Service: 402 o := &api.SRv6L3ServiceTLV{} 403 o.SubTlvs, err = MarshalSRv6SubTLVs(t.SubTLVs) 404 if err != nil { 405 return nil, err 406 } 407 r = o 408 case bgp.TLVTypeSRv6L2Service: 409 o := &api.SRv6L2ServiceTLV{} 410 o.SubTlvs, err = MarshalSRv6SubTLVs(t.SubTLVs) 411 if err != nil { 412 return nil, err 413 } 414 r = o 415 } 416 default: 417 return nil, fmt.Errorf("invalid prefix sid tlv type to marshal %v", t) 418 } 419 a, _ := apb.New(r) 420 mtlvs[i] = a 421 } 422 423 return mtlvs, nil 424 } 425 426 func MarshalSRv6SubTLVs(tlvs []bgp.PrefixSIDTLVInterface) (map[uint32]*api.SRv6TLV, error) { 427 mtlvs := make(map[uint32]*api.SRv6TLV) 428 var key uint32 429 for _, tlv := range tlvs { 430 var r proto.Message 431 switch t := tlv.(type) { 432 case *bgp.SRv6InformationSubTLV: 433 o := &api.SRv6InformationSubTLV{ 434 EndpointBehavior: uint32(t.EndpointBehavior), 435 // TODO Once flags are used in RFC, add processing. 436 Flags: &api.SRv6SIDFlags{}, 437 } 438 o.Sid = make([]byte, len(t.SID)) 439 copy(o.Sid, t.SID) 440 var err error 441 o.SubSubTlvs, err = MarshalSRv6SubSubTLVs(t.SubSubTLVs) 442 if err != nil { 443 return nil, err 444 } 445 // SRv6 Information Sub TLV is type 1 Sub TLV 446 key = 1 447 r = o 448 default: 449 return nil, fmt.Errorf("invalid prefix sid sub tlv type to marshal: %v", t) 450 } 451 a, _ := apb.New(r) 452 tlvs, ok := mtlvs[key] 453 if !ok { 454 tlvs = &api.SRv6TLV{ 455 Tlv: make([]*apb.Any, 0), 456 } 457 mtlvs[key] = tlvs 458 } 459 tlvs.Tlv = append(tlvs.Tlv, a) 460 } 461 462 return mtlvs, nil 463 } 464 465 func MarshalSRv6SubSubTLVs(tlvs []bgp.PrefixSIDTLVInterface) (map[uint32]*api.SRv6TLV, error) { 466 mtlvs := make(map[uint32]*api.SRv6TLV) 467 var key uint32 468 for _, tlv := range tlvs { 469 var r proto.Message 470 switch t := tlv.(type) { 471 case *bgp.SRv6SIDStructureSubSubTLV: 472 o := &api.SRv6StructureSubSubTLV{ 473 LocatorBlockLength: uint32(t.LocatorBlockLength), 474 LocatorNodeLength: uint32(t.LocatorNodeLength), 475 FunctionLength: uint32(t.FunctionLength), 476 ArgumentLength: uint32(t.ArgumentLength), 477 TranspositionLength: uint32(t.TranspositionLength), 478 TranspositionOffset: uint32(t.TranspositionOffset), 479 } 480 // SRv6 SID Structure Sub Sub TLV is type 1 Sub Sub TLV 481 key = 1 482 r = o 483 default: 484 return nil, fmt.Errorf("invalid prefix sid sub sub tlv type to marshal: %v", t) 485 } 486 a, _ := apb.New(r) 487 tlvs, ok := mtlvs[key] 488 if !ok { 489 tlvs = &api.SRv6TLV{ 490 Tlv: make([]*apb.Any, 0), 491 } 492 mtlvs[key] = tlvs 493 } 494 tlvs.Tlv = append(tlvs.Tlv, a) 495 } 496 return mtlvs, nil 497 } 498 499 func MarshalRD(rd bgp.RouteDistinguisherInterface) (*apb.Any, error) { 500 var r proto.Message 501 switch v := rd.(type) { 502 case *bgp.RouteDistinguisherTwoOctetAS: 503 r = &api.RouteDistinguisherTwoOctetASN{ 504 Admin: uint32(v.Admin), 505 Assigned: v.Assigned, 506 } 507 case *bgp.RouteDistinguisherIPAddressAS: 508 r = &api.RouteDistinguisherIPAddress{ 509 Admin: v.Admin.String(), 510 Assigned: uint32(v.Assigned), 511 } 512 case *bgp.RouteDistinguisherFourOctetAS: 513 r = &api.RouteDistinguisherFourOctetASN{ 514 Admin: v.Admin, 515 Assigned: uint32(v.Assigned), 516 } 517 default: 518 return nil, fmt.Errorf("invalid rd type to marshal: %v", rd) 519 } 520 a, _ := apb.New(r) 521 return a, nil 522 } 523 524 func UnmarshalRD(a *apb.Any) (bgp.RouteDistinguisherInterface, error) { 525 value, err := a.UnmarshalNew() 526 if err != nil { 527 return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) 528 } 529 switch v := value.(type) { 530 case *api.RouteDistinguisherTwoOctetASN: 531 return bgp.NewRouteDistinguisherTwoOctetAS(uint16(v.Admin), v.Assigned), nil 532 case *api.RouteDistinguisherIPAddress: 533 rd := bgp.NewRouteDistinguisherIPAddressAS(v.Admin, uint16(v.Assigned)) 534 if rd == nil { 535 return nil, fmt.Errorf("invalid address for route distinguisher: %s", v.Admin) 536 } 537 return rd, nil 538 case *api.RouteDistinguisherFourOctetASN: 539 return bgp.NewRouteDistinguisherFourOctetAS(v.Admin, uint16(v.Assigned)), nil 540 } 541 return nil, fmt.Errorf("invalid route distinguisher type: %s", a.TypeUrl) 542 } 543 544 func NewEthernetSegmentIdentifierFromNative(a *bgp.EthernetSegmentIdentifier) (*api.EthernetSegmentIdentifier, error) { 545 return &api.EthernetSegmentIdentifier{ 546 Type: uint32(a.Type), 547 Value: a.Value, 548 }, nil 549 } 550 551 func unmarshalESI(a *api.EthernetSegmentIdentifier) (*bgp.EthernetSegmentIdentifier, error) { 552 return &bgp.EthernetSegmentIdentifier{ 553 Type: bgp.ESIType(a.Type), 554 Value: a.Value, 555 }, nil 556 } 557 558 func MarshalFlowSpecRules(values []bgp.FlowSpecComponentInterface) ([]*apb.Any, error) { 559 rules := make([]*apb.Any, 0, len(values)) 560 for _, value := range values { 561 var rule proto.Message 562 switch v := value.(type) { 563 case *bgp.FlowSpecDestinationPrefix: 564 rule = &api.FlowSpecIPPrefix{ 565 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), 566 PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), 567 Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), 568 } 569 case *bgp.FlowSpecSourcePrefix: 570 rule = &api.FlowSpecIPPrefix{ 571 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), 572 PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), 573 Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), 574 } 575 case *bgp.FlowSpecDestinationPrefix6: 576 rule = &api.FlowSpecIPPrefix{ 577 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), 578 PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), 579 Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), 580 Offset: uint32(v.Offset), 581 } 582 case *bgp.FlowSpecSourcePrefix6: 583 rule = &api.FlowSpecIPPrefix{ 584 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), 585 PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), 586 Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), 587 Offset: uint32(v.Offset), 588 } 589 case *bgp.FlowSpecSourceMac: 590 rule = &api.FlowSpecMAC{ 591 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_MAC), 592 Address: v.Mac.String(), 593 } 594 case *bgp.FlowSpecDestinationMac: 595 rule = &api.FlowSpecMAC{ 596 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_MAC), 597 Address: v.Mac.String(), 598 } 599 case *bgp.FlowSpecComponent: 600 items := make([]*api.FlowSpecComponentItem, 0, len(v.Items)) 601 for _, i := range v.Items { 602 items = append(items, &api.FlowSpecComponentItem{ 603 Op: uint32(i.Op), 604 Value: i.Value, 605 }) 606 } 607 rule = &api.FlowSpecComponent{ 608 Type: uint32(v.Type()), 609 Items: items, 610 } 611 } 612 a, _ := apb.New(rule) 613 rules = append(rules, a) 614 } 615 return rules, nil 616 } 617 618 func UnmarshalFlowSpecRules(values []*apb.Any) ([]bgp.FlowSpecComponentInterface, error) { 619 rules := make([]bgp.FlowSpecComponentInterface, 0, len(values)) 620 for _, an := range values { 621 var rule bgp.FlowSpecComponentInterface 622 value, err := an.UnmarshalNew() 623 if err != nil { 624 return nil, fmt.Errorf("failed to unmarshal flow spec component: %s", err) 625 } 626 switch v := value.(type) { 627 case *api.FlowSpecIPPrefix: 628 typ := bgp.BGPFlowSpecType(v.Type) 629 isIPv4 := net.ParseIP(v.Prefix).To4() != nil 630 switch { 631 case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && isIPv4: 632 rule = bgp.NewFlowSpecDestinationPrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) 633 case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && isIPv4: 634 rule = bgp.NewFlowSpecSourcePrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) 635 case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && !isIPv4: 636 rule = bgp.NewFlowSpecDestinationPrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) 637 case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && !isIPv4: 638 rule = bgp.NewFlowSpecSourcePrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) 639 } 640 case *api.FlowSpecMAC: 641 typ := bgp.BGPFlowSpecType(v.Type) 642 mac, err := net.ParseMAC(v.Address) 643 if err != nil { 644 return nil, fmt.Errorf("invalid mac address for %s flow spec component: %s", typ.String(), v.Address) 645 } 646 switch typ { 647 case bgp.FLOW_SPEC_TYPE_SRC_MAC: 648 rule = bgp.NewFlowSpecSourceMac(mac) 649 case bgp.FLOW_SPEC_TYPE_DST_MAC: 650 rule = bgp.NewFlowSpecDestinationMac(mac) 651 } 652 case *api.FlowSpecComponent: 653 items := make([]*bgp.FlowSpecComponentItem, 0, len(v.Items)) 654 for _, item := range v.Items { 655 items = append(items, bgp.NewFlowSpecComponentItem(uint8(item.Op), item.Value)) 656 } 657 rule = bgp.NewFlowSpecComponent(bgp.BGPFlowSpecType(v.Type), items) 658 } 659 if rule == nil { 660 return nil, fmt.Errorf("invalid flow spec component: %v", value) 661 } 662 rules = append(rules, rule) 663 } 664 return rules, nil 665 } 666 667 func MarshalLsNodeDescriptor(d *bgp.LsNodeDescriptor) (*api.LsNodeDescriptor, error) { 668 return &api.LsNodeDescriptor{ 669 Asn: d.Asn, 670 BgpLsId: d.BGPLsID, 671 OspfAreaId: d.OspfAreaID, 672 Pseudonode: d.PseudoNode, 673 IgpRouterId: d.IGPRouterID, 674 BgpRouterId: d.BGPRouterID.String(), 675 BgpConfederationMember: d.BGPConfederationMember, 676 }, nil 677 } 678 679 func MarshalLsLinkDescriptor(n *bgp.LsLinkDescriptor) (*api.LsLinkDescriptor, error) { 680 return &api.LsLinkDescriptor{ 681 LinkLocalId: uint32OrDefault(n.LinkLocalID), 682 LinkRemoteId: uint32OrDefault(n.LinkRemoteID), 683 InterfaceAddrIpv4: ipOrDefault(n.InterfaceAddrIPv4), 684 NeighborAddrIpv4: ipOrDefault(n.NeighborAddrIPv4), 685 InterfaceAddrIpv6: ipOrDefault(n.InterfaceAddrIPv6), 686 NeighborAddrIpv6: ipOrDefault(n.NeighborAddrIPv6), 687 }, nil 688 } 689 690 func MarshalLsPrefixDescriptor(d *bgp.LsPrefixDescriptor) (*api.LsPrefixDescriptor, error) { 691 p := &api.LsPrefixDescriptor{ 692 OspfRouteType: api.LsOspfRouteType(d.OSPFRouteType), 693 } 694 695 for _, ip := range d.IPReachability { 696 p.IpReachability = append(p.IpReachability, ip.String()) 697 } 698 return p, nil 699 } 700 701 func MarshalLsNodeNLRI(n *bgp.LsNodeNLRI) (*apb.Any, error) { 702 ln, err := MarshalLsNodeDescriptor(n.LocalNodeDesc.(*bgp.LsTLVNodeDescriptor).Extract()) 703 if err != nil { 704 return nil, err 705 } 706 node := &api.LsNodeNLRI{ 707 LocalNode: ln, 708 } 709 a, _ := apb.New(node) 710 711 return a, nil 712 } 713 714 func MarshalLsLinkNLRI(n *bgp.LsLinkNLRI) (*apb.Any, error) { 715 desc := &bgp.LsLinkDescriptor{} 716 desc.ParseTLVs(n.LinkDesc) 717 718 var err error 719 ln, err := MarshalLsNodeDescriptor(n.LocalNodeDesc.(*bgp.LsTLVNodeDescriptor).Extract()) 720 if err != nil { 721 return nil, err 722 } 723 rn, err := MarshalLsNodeDescriptor(n.RemoteNodeDesc.(*bgp.LsTLVNodeDescriptor).Extract()) 724 if err != nil { 725 return nil, err 726 } 727 728 ld, err := MarshalLsLinkDescriptor(desc) 729 if err != nil { 730 return nil, err 731 } 732 733 link := &api.LsLinkNLRI{ 734 LocalNode: ln, 735 RemoteNode: rn, 736 LinkDescriptor: ld, 737 } 738 a, _ := apb.New(link) 739 740 return a, nil 741 } 742 743 func MarshalLsPrefixV4NLRI(n *bgp.LsPrefixV4NLRI) (*apb.Any, error) { 744 desc := &bgp.LsPrefixDescriptor{} 745 desc.ParseTLVs(n.PrefixDesc, false) 746 747 ln, err := MarshalLsNodeDescriptor(n.LocalNodeDesc.(*bgp.LsTLVNodeDescriptor).Extract()) 748 if err != nil { 749 return nil, err 750 } 751 752 pd, err := MarshalLsPrefixDescriptor(desc) 753 if err != nil { 754 return nil, err 755 } 756 757 prefix := &api.LsPrefixV4NLRI{ 758 LocalNode: ln, 759 PrefixDescriptor: pd, 760 } 761 a, _ := apb.New(prefix) 762 763 return a, nil 764 } 765 766 func MarshalLsPrefixV6NLRI(n *bgp.LsPrefixV6NLRI) (*apb.Any, error) { 767 desc := &bgp.LsPrefixDescriptor{} 768 desc.ParseTLVs(n.PrefixDesc, true) 769 770 ln, err := MarshalLsNodeDescriptor(n.LocalNodeDesc.(*bgp.LsTLVNodeDescriptor).Extract()) 771 if err != nil { 772 return nil, err 773 } 774 775 pd, err := MarshalLsPrefixDescriptor(desc) 776 if err != nil { 777 return nil, err 778 } 779 780 prefix := &api.LsPrefixV6NLRI{ 781 LocalNode: ln, 782 PrefixDescriptor: pd, 783 } 784 a, _ := apb.New(prefix) 785 786 return a, nil 787 } 788 789 func MarshalLsBgpPeerSegmentSid(n *bgp.LsBgpPeerSegmentSID) (*api.LsBgpPeerSegmentSID, error) { 790 flags := &api.LsBgpPeerSegmentSIDFlags{ 791 Value: n.Flags.Value, 792 Local: n.Flags.Local, 793 Backup: n.Flags.Backup, 794 Persistent: n.Flags.Persistent, 795 } 796 sid := &api.LsBgpPeerSegmentSID{ 797 Flags: flags, 798 Weight: uint32(n.Weight), 799 Sid: n.SID, 800 } 801 802 return sid, nil 803 } 804 func UnmarshalLsBgpPeerSegmentSid(a *api.LsBgpPeerSegmentSID) (*bgp.LsBgpPeerSegmentSID, error) { 805 flags := &bgp.LsAttributeBgpPeerSegmentSIDFlags{ 806 Value: a.Flags.Value, 807 Local: a.Flags.Local, 808 Backup: a.Flags.Backup, 809 Persistent: a.Flags.Persistent, 810 } 811 812 sid := &bgp.LsBgpPeerSegmentSID{ 813 Flags: *flags, 814 Weight: uint8(a.Weight), 815 SID: a.Sid, 816 } 817 818 return sid, nil 819 } 820 821 func UnmarshalLsNodeDescriptor(nd *api.LsNodeDescriptor) (*bgp.LsNodeDescriptor, error) { 822 return &bgp.LsNodeDescriptor{ 823 Asn: nd.Asn, 824 BGPLsID: nd.BgpLsId, 825 OspfAreaID: nd.OspfAreaId, 826 PseudoNode: nd.Pseudonode, 827 IGPRouterID: nd.IgpRouterId, 828 BGPRouterID: net.ParseIP(nd.BgpRouterId), 829 BGPConfederationMember: nd.BgpConfederationMember, 830 }, nil 831 } 832 833 func UnmarshalLsLinkDescriptor(ld *api.LsLinkDescriptor) (*bgp.LsLinkDescriptor, error) { 834 ifAddrIPv4 := net.IP{} 835 neiAddrIPv4 := net.IP{} 836 ifAddrIPv6 := net.IP{} 837 neiAddrIPv6 := net.IP{} 838 839 if ld.GetInterfaceAddrIpv4() != "" { 840 ifAddrIPv4 = net.ParseIP(ld.InterfaceAddrIpv4).To4() 841 } 842 if ld.GetNeighborAddrIpv4() != "" { 843 neiAddrIPv4 = net.ParseIP(ld.NeighborAddrIpv4).To4() 844 } 845 if ld.GetInterfaceAddrIpv6() != "" { 846 ifAddrIPv6 = net.ParseIP(ld.InterfaceAddrIpv6).To16() 847 } 848 if ld.GetNeighborAddrIpv6() != "" { 849 neiAddrIPv6 = net.ParseIP(ld.NeighborAddrIpv6).To16() 850 } 851 852 return &bgp.LsLinkDescriptor{ 853 LinkLocalID: &ld.LinkLocalId, 854 LinkRemoteID: &ld.LinkRemoteId, 855 InterfaceAddrIPv4: &ifAddrIPv4, 856 NeighborAddrIPv4: &neiAddrIPv4, 857 InterfaceAddrIPv6: &ifAddrIPv6, 858 NeighborAddrIPv6: &neiAddrIPv6, 859 }, nil 860 } 861 862 func UnmarshalPrefixDescriptor(pd *api.LsPrefixDescriptor) (*bgp.LsPrefixDescriptor, error) { 863 ipReachability := []net.IPNet{} 864 for _, reach := range pd.IpReachability { 865 _, ipnet, _ := net.ParseCIDR(reach) 866 ipReachability = append(ipReachability, *ipnet) 867 } 868 869 ospfRouteType := bgp.LsOspfRouteType(pd.OspfRouteType) 870 871 return &bgp.LsPrefixDescriptor{ 872 IPReachability: ipReachability, 873 OSPFRouteType: ospfRouteType, 874 }, nil 875 } 876 877 func UnmarshalLsPrefixDescriptor(*api.LsPrefixDescriptor) (*bgp.LsPrefixDescriptor, error) { 878 return nil, nil 879 } 880 881 func UnmarshalLsAttribute(a *api.LsAttribute) (*bgp.LsAttribute, error) { 882 lsAttr := &bgp.LsAttribute{ 883 Node: bgp.LsAttributeNode{}, 884 Link: bgp.LsAttributeLink{}, 885 Prefix: bgp.LsAttributePrefix{}, 886 BgpPeerSegment: bgp.LsAttributeBgpPeerSegment{}, 887 } 888 889 // For AttributeNode 890 if a.Node != nil { 891 nodeLocalRouterID := net.ParseIP(a.Node.LocalRouterId) 892 nodeLocalRouterIDv6 := net.ParseIP(a.Node.LocalRouterIdV6) 893 srCapabilitiesRanges := []bgp.LsSrRange{} 894 if a.Node.SrCapabilities != nil { 895 for _, r := range a.Node.SrCapabilities.Ranges { 896 srCapabilitiesRanges = append(srCapabilitiesRanges, bgp.LsSrRange{ 897 Begin: r.Begin, 898 End: r.End, 899 }) 900 } 901 } 902 srLocalBlockRanges := []bgp.LsSrRange{} 903 if a.Node.SrLocalBlock != nil { 904 for _, r := range a.Node.SrLocalBlock.Ranges { 905 srLocalBlockRanges = append(srLocalBlockRanges, bgp.LsSrRange{ 906 Begin: r.Begin, 907 End: r.End, 908 }) 909 } 910 lsAttr.Node = bgp.LsAttributeNode{ 911 Flags: &bgp.LsNodeFlags{ 912 Overload: a.Node.Flags.Overload, 913 Attached: a.Node.Flags.Attached, 914 External: a.Node.Flags.External, 915 ABR: a.Node.Flags.Abr, 916 Router: a.Node.Flags.Router, 917 V6: a.Node.Flags.V6, 918 }, 919 Opaque: &a.Node.Opaque, 920 Name: &a.Node.Name, 921 IsisArea: &a.Node.IsisArea, 922 LocalRouterID: &nodeLocalRouterID, 923 LocalRouterIDv6: &nodeLocalRouterIDv6, 924 SrCapabilties: &bgp.LsSrCapabilities{ 925 IPv4Supported: a.Node.SrCapabilities.Ipv4Supported, 926 IPv6Supported: a.Node.SrCapabilities.Ipv6Supported, 927 Ranges: srCapabilitiesRanges, 928 }, 929 SrAlgorithms: &a.Node.SrAlgorithms, 930 SrLocalBlock: &bgp.LsSrLocalBlock{ 931 Ranges: srLocalBlockRanges, 932 }, 933 } 934 } 935 } 936 937 // For AttributeLink 938 if a.Link != nil { 939 var linkName *string 940 if a.Link.Name != "" { 941 linkName = &a.Link.Name 942 } 943 linkLocalRouterID := (*net.IP)(nil) 944 if a.Link.LocalRouterId != "" { 945 localRouterID := net.ParseIP(a.Link.LocalRouterId) 946 linkLocalRouterID = &localRouterID 947 } 948 linkLocalRouterIDv6 := (*net.IP)(nil) 949 if a.Link.LocalRouterIdV6 != "" { 950 localRouterIDv6 := net.ParseIP(a.Link.LocalRouterIdV6) 951 linkLocalRouterIDv6 = &localRouterIDv6 952 } 953 linkRemoteRouterID := (*net.IP)(nil) 954 if a.Link.RemoteRouterId != "" { 955 remoteRouterID := net.ParseIP(a.Link.RemoteRouterId) 956 linkRemoteRouterID = &remoteRouterID 957 } 958 linkRemoteRouterIDv6 := (*net.IP)(nil) 959 if a.Link.RemoteRouterIdV6 != "" { 960 remoteRouterIDv6 := net.ParseIP(a.Link.RemoteRouterIdV6) 961 linkRemoteRouterIDv6 = &remoteRouterIDv6 962 } 963 var linkAdminGroup *uint32 964 if a.Link.AdminGroup != 0 { 965 linkAdminGroup = &a.Link.AdminGroup 966 } 967 var linkDefaultTeMetric *uint32 968 if a.Link.DefaultTeMetric != 0 { 969 linkDefaultTeMetric = &a.Link.DefaultTeMetric 970 } 971 var linkIgpMetric *uint32 972 if a.Link.IgpMetric != 0 { 973 linkIgpMetric = &a.Link.IgpMetric 974 } 975 var linkOpaque *[]byte 976 if len(a.Link.Opaque) != 0 { 977 linkOpaque = &a.Link.Opaque 978 } 979 var linkBandwidth *float32 980 if a.Link.Bandwidth != 0 { 981 linkBandwidth = &a.Link.Bandwidth 982 } 983 var linkReservableBandwidth *float32 984 if a.Link.ReservableBandwidth != 0 { 985 linkBandwidth = &a.Link.ReservableBandwidth 986 } 987 unreservedBandwidth := [8]float32{} 988 if a.Link.UnreservedBandwidth != nil { 989 copy(unreservedBandwidth[:], a.Link.UnreservedBandwidth) 990 } 991 var linkSrlgs *[]uint32 992 if a.Link.Srlgs != nil { 993 linkSrlgs = &a.Link.Srlgs 994 } 995 var linkSrAdjacencySid *uint32 996 if a.Link.SrAdjacencySid != 0 { 997 linkSrAdjacencySid = &a.Link.SrAdjacencySid 998 } 999 lsAttr.Link = bgp.LsAttributeLink{ 1000 Name: linkName, 1001 LocalRouterID: linkLocalRouterID, 1002 LocalRouterIDv6: linkLocalRouterIDv6, 1003 RemoteRouterID: linkRemoteRouterID, 1004 RemoteRouterIDv6: linkRemoteRouterIDv6, 1005 AdminGroup: linkAdminGroup, 1006 DefaultTEMetric: linkDefaultTeMetric, 1007 IGPMetric: linkIgpMetric, 1008 Opaque: linkOpaque, 1009 Bandwidth: linkBandwidth, 1010 ReservableBandwidth: linkReservableBandwidth, 1011 UnreservedBandwidth: &unreservedBandwidth, 1012 Srlgs: linkSrlgs, 1013 SrAdjacencySID: linkSrAdjacencySid, 1014 } 1015 } 1016 1017 // For AttributePrefix 1018 if a.Prefix != nil { 1019 if a.Prefix.IgpFlags != nil { 1020 lsAttr.Prefix = bgp.LsAttributePrefix{ 1021 IGPFlags: &bgp.LsIGPFlags{ 1022 Down: a.Prefix.IgpFlags.Down, 1023 NoUnicast: a.Prefix.IgpFlags.NoUnicast, 1024 LocalAddress: a.Prefix.IgpFlags.LocalAddress, 1025 PropagateNSSA: a.Prefix.IgpFlags.PropagateNssa, 1026 }, 1027 Opaque: &a.Prefix.Opaque, 1028 SrPrefixSID: &a.Prefix.SrPrefixSid, 1029 } 1030 } 1031 } 1032 1033 // For AttributeBgpPeerSegment 1034 if a.BgpPeerSegment != nil { 1035 lsAttributeBgpPeerSegment := bgp.LsAttributeBgpPeerSegment{} 1036 if a.BgpPeerSegment.BgpPeerNodeSid != nil { 1037 lsAttributeBgpPeerSegment.BgpPeerNodeSid, _ = UnmarshalLsBgpPeerSegmentSid(a.BgpPeerSegment.BgpPeerNodeSid) 1038 } 1039 if a.BgpPeerSegment.BgpPeerAdjacencySid != nil { 1040 lsAttributeBgpPeerSegment.BgpPeerAdjacencySid, _ = UnmarshalLsBgpPeerSegmentSid(a.BgpPeerSegment.BgpPeerAdjacencySid) 1041 } 1042 if a.BgpPeerSegment.BgpPeerSetSid != nil { 1043 lsAttributeBgpPeerSegment.BgpPeerSetSid, _ = UnmarshalLsBgpPeerSegmentSid(a.BgpPeerSegment.BgpPeerSetSid) 1044 } 1045 lsAttr.BgpPeerSegment = lsAttributeBgpPeerSegment 1046 } 1047 1048 return lsAttr, nil 1049 } 1050 1051 func MarshalNLRI(value bgp.AddrPrefixInterface) (*apb.Any, error) { 1052 var nlri proto.Message 1053 1054 switch v := value.(type) { 1055 case *bgp.IPAddrPrefix: 1056 nlri = &api.IPAddressPrefix{ 1057 PrefixLen: uint32(v.Length), 1058 Prefix: v.Prefix.String(), 1059 } 1060 case *bgp.IPv6AddrPrefix: 1061 nlri = &api.IPAddressPrefix{ 1062 PrefixLen: uint32(v.Length), 1063 Prefix: v.Prefix.String(), 1064 } 1065 case *bgp.LabeledIPAddrPrefix: 1066 nlri = &api.LabeledIPAddressPrefix{ 1067 Labels: v.Labels.Labels, 1068 PrefixLen: uint32(v.IPPrefixLen()), 1069 Prefix: v.Prefix.String(), 1070 } 1071 case *bgp.LabeledIPv6AddrPrefix: 1072 nlri = &api.LabeledIPAddressPrefix{ 1073 Labels: v.Labels.Labels, 1074 PrefixLen: uint32(v.IPPrefixLen()), 1075 Prefix: v.Prefix.String(), 1076 } 1077 case *bgp.EncapNLRI: 1078 nlri = &api.EncapsulationNLRI{ 1079 Address: v.String(), 1080 } 1081 case *bgp.Encapv6NLRI: 1082 nlri = &api.EncapsulationNLRI{ 1083 Address: v.String(), 1084 } 1085 case *bgp.VPLSNLRI: 1086 rd, err := MarshalRD(v.RD()) 1087 if err != nil { 1088 return nil, err 1089 } 1090 nlri = &api.VPLSNLRI{ 1091 Rd: rd, 1092 VeId: uint32(v.VEID), 1093 VeBlockOffset: uint32(v.VEBlockOffset), 1094 VeBlockSize: uint32(v.VEBlockSize), 1095 LabelBlockBase: v.LabelBlockBase, 1096 } 1097 case *bgp.EVPNNLRI: 1098 switch r := v.RouteTypeData.(type) { 1099 case *bgp.EVPNEthernetAutoDiscoveryRoute: 1100 rd, err := MarshalRD(r.RD) 1101 if err != nil { 1102 return nil, err 1103 } 1104 esi, err := NewEthernetSegmentIdentifierFromNative(&r.ESI) 1105 if err != nil { 1106 return nil, err 1107 } 1108 1109 nlri = &api.EVPNEthernetAutoDiscoveryRoute{ 1110 Rd: rd, 1111 Esi: esi, 1112 EthernetTag: r.ETag, 1113 Label: r.Label, 1114 } 1115 case *bgp.EVPNMacIPAdvertisementRoute: 1116 rd, err := MarshalRD(r.RD) 1117 if err != nil { 1118 return nil, err 1119 } 1120 esi, err := NewEthernetSegmentIdentifierFromNative(&r.ESI) 1121 if err != nil { 1122 return nil, err 1123 } 1124 1125 nlri = &api.EVPNMACIPAdvertisementRoute{ 1126 Rd: rd, 1127 Esi: esi, 1128 EthernetTag: r.ETag, 1129 MacAddress: r.MacAddress.String(), 1130 IpAddress: r.IPAddress.String(), 1131 Labels: r.Labels, 1132 } 1133 case *bgp.EVPNMulticastEthernetTagRoute: 1134 rd, err := MarshalRD(r.RD) 1135 if err != nil { 1136 return nil, err 1137 } 1138 nlri = &api.EVPNInclusiveMulticastEthernetTagRoute{ 1139 Rd: rd, 1140 EthernetTag: r.ETag, 1141 IpAddress: r.IPAddress.String(), 1142 } 1143 case *bgp.EVPNEthernetSegmentRoute: 1144 rd, err := MarshalRD(r.RD) 1145 if err != nil { 1146 return nil, err 1147 } 1148 esi, err := NewEthernetSegmentIdentifierFromNative(&r.ESI) 1149 if err != nil { 1150 return nil, err 1151 } 1152 nlri = &api.EVPNEthernetSegmentRoute{ 1153 Rd: rd, 1154 Esi: esi, 1155 IpAddress: r.IPAddress.String(), 1156 } 1157 case *bgp.EVPNIPPrefixRoute: 1158 rd, err := MarshalRD(r.RD) 1159 if err != nil { 1160 return nil, err 1161 } 1162 esi, err := NewEthernetSegmentIdentifierFromNative(&r.ESI) 1163 if err != nil { 1164 return nil, err 1165 } 1166 nlri = &api.EVPNIPPrefixRoute{ 1167 Rd: rd, 1168 Esi: esi, 1169 EthernetTag: r.ETag, 1170 IpPrefix: r.IPPrefix.String(), 1171 IpPrefixLen: uint32(r.IPPrefixLength), 1172 Label: r.Label, 1173 GwAddress: r.GWIPAddress.String(), 1174 } 1175 } 1176 case *bgp.LabeledVPNIPAddrPrefix: 1177 rd, err := MarshalRD(v.RD) 1178 if err != nil { 1179 return nil, err 1180 } 1181 nlri = &api.LabeledVPNIPAddressPrefix{ 1182 Labels: v.Labels.Labels, 1183 Rd: rd, 1184 PrefixLen: uint32(v.IPPrefixLen()), 1185 Prefix: v.Prefix.String(), 1186 } 1187 case *bgp.LabeledVPNIPv6AddrPrefix: 1188 rd, err := MarshalRD(v.RD) 1189 if err != nil { 1190 return nil, err 1191 } 1192 nlri = &api.LabeledVPNIPAddressPrefix{ 1193 Labels: v.Labels.Labels, 1194 Rd: rd, 1195 PrefixLen: uint32(v.IPPrefixLen()), 1196 Prefix: v.Prefix.String(), 1197 } 1198 case *bgp.RouteTargetMembershipNLRI: 1199 rt, err := MarshalRT(v.RouteTarget) 1200 if err != nil { 1201 return nil, err 1202 } 1203 nlri = &api.RouteTargetMembershipNLRI{ 1204 Asn: v.AS, 1205 Rt: rt, 1206 } 1207 case *bgp.FlowSpecIPv4Unicast: 1208 rules, err := MarshalFlowSpecRules(v.Value) 1209 if err != nil { 1210 return nil, err 1211 } 1212 nlri = &api.FlowSpecNLRI{ 1213 Rules: rules, 1214 } 1215 case *bgp.FlowSpecIPv6Unicast: 1216 rules, err := MarshalFlowSpecRules(v.Value) 1217 if err != nil { 1218 return nil, err 1219 } 1220 nlri = &api.FlowSpecNLRI{ 1221 Rules: rules, 1222 } 1223 case *bgp.FlowSpecIPv4VPN: 1224 rd, err := MarshalRD(v.RD()) 1225 if err != nil { 1226 return nil, err 1227 } 1228 rules, err := MarshalFlowSpecRules(v.Value) 1229 if err != nil { 1230 return nil, err 1231 } 1232 nlri = &api.VPNFlowSpecNLRI{ 1233 Rd: rd, 1234 Rules: rules, 1235 } 1236 case *bgp.FlowSpecIPv6VPN: 1237 rd, err := MarshalRD(v.RD()) 1238 if err != nil { 1239 return nil, err 1240 } 1241 rules, err := MarshalFlowSpecRules(v.Value) 1242 if err != nil { 1243 return nil, err 1244 } 1245 nlri = &api.VPNFlowSpecNLRI{ 1246 Rd: rd, 1247 Rules: rules, 1248 } 1249 case *bgp.FlowSpecL2VPN: 1250 rd, err := MarshalRD(v.RD()) 1251 if err != nil { 1252 return nil, err 1253 } 1254 rules, err := MarshalFlowSpecRules(v.Value) 1255 if err != nil { 1256 return nil, err 1257 } 1258 nlri = &api.VPNFlowSpecNLRI{ 1259 Rd: rd, 1260 Rules: rules, 1261 } 1262 case *bgp.LsAddrPrefix: 1263 switch n := v.NLRI.(type) { 1264 case *bgp.LsNodeNLRI: 1265 node, err := MarshalLsNodeNLRI(n) 1266 if err != nil { 1267 return nil, err 1268 } 1269 nlri = &api.LsAddrPrefix{ 1270 Type: api.LsNLRIType_LS_NLRI_NODE, 1271 Nlri: node, 1272 Length: uint32(n.Length), 1273 ProtocolId: api.LsProtocolID(n.ProtocolID), 1274 Identifier: n.Identifier, 1275 } 1276 1277 case *bgp.LsLinkNLRI: 1278 node, err := MarshalLsLinkNLRI(n) 1279 if err != nil { 1280 return nil, err 1281 } 1282 nlri = &api.LsAddrPrefix{ 1283 Type: api.LsNLRIType_LS_NLRI_LINK, 1284 Nlri: node, 1285 Length: uint32(n.Length), 1286 ProtocolId: api.LsProtocolID(n.ProtocolID), 1287 Identifier: n.Identifier, 1288 } 1289 1290 case *bgp.LsPrefixV4NLRI: 1291 node, err := MarshalLsPrefixV4NLRI(n) 1292 if err != nil { 1293 return nil, err 1294 } 1295 nlri = &api.LsAddrPrefix{ 1296 Type: api.LsNLRIType_LS_NLRI_PREFIX_V4, 1297 Nlri: node, 1298 Length: uint32(n.Length), 1299 ProtocolId: api.LsProtocolID(n.ProtocolID), 1300 Identifier: n.Identifier, 1301 } 1302 1303 case *bgp.LsPrefixV6NLRI: 1304 node, err := MarshalLsPrefixV6NLRI(n) 1305 if err != nil { 1306 return nil, err 1307 } 1308 nlri = &api.LsAddrPrefix{ 1309 Type: api.LsNLRIType_LS_NLRI_PREFIX_V6, 1310 Nlri: node, 1311 Length: uint32(n.Length), 1312 ProtocolId: api.LsProtocolID(n.ProtocolID), 1313 Identifier: n.Identifier, 1314 } 1315 } 1316 case *bgp.SRPolicyIPv4: 1317 nlri = &api.SRPolicyNLRI{ 1318 Length: uint32(v.Length), 1319 Distinguisher: v.Distinguisher, 1320 Color: v.Color, 1321 Endpoint: v.Endpoint, 1322 } 1323 case *bgp.SRPolicyIPv6: 1324 nlri = &api.SRPolicyNLRI{ 1325 Length: uint32(v.Length), 1326 Distinguisher: v.Distinguisher, 1327 Color: v.Color, 1328 Endpoint: v.Endpoint, 1329 } 1330 case *bgp.MUPNLRI: 1331 switch r := v.RouteTypeData.(type) { 1332 case *bgp.MUPInterworkSegmentDiscoveryRoute: 1333 rd, err := MarshalRD(r.RD) 1334 if err != nil { 1335 return nil, err 1336 } 1337 nlri = &api.MUPInterworkSegmentDiscoveryRoute{ 1338 Rd: rd, 1339 Prefix: r.Prefix.String(), 1340 } 1341 case *bgp.MUPDirectSegmentDiscoveryRoute: 1342 rd, err := MarshalRD(r.RD) 1343 if err != nil { 1344 return nil, err 1345 } 1346 nlri = &api.MUPDirectSegmentDiscoveryRoute{ 1347 Rd: rd, 1348 Address: r.Address.String(), 1349 } 1350 case *bgp.MUPType1SessionTransformedRoute: 1351 rd, err := MarshalRD(r.RD) 1352 if err != nil { 1353 return nil, err 1354 } 1355 var sal uint32 1356 var sa string 1357 if r.SourceAddressLength > 0 && r.SourceAddress != nil { 1358 sal = uint32(r.SourceAddressLength) 1359 sa = r.SourceAddress.String() 1360 } 1361 nlri = &api.MUPType1SessionTransformedRoute{ 1362 Rd: rd, 1363 Prefix: r.Prefix.String(), 1364 Teid: binary.BigEndian.Uint32(r.TEID.AsSlice()), 1365 Qfi: uint32(r.QFI), 1366 EndpointAddressLength: uint32(r.EndpointAddressLength), 1367 EndpointAddress: r.EndpointAddress.String(), 1368 SourceAddressLength: sal, 1369 SourceAddress: sa, 1370 } 1371 case *bgp.MUPType2SessionTransformedRoute: 1372 rd, err := MarshalRD(r.RD) 1373 if err != nil { 1374 return nil, err 1375 } 1376 ar := &api.MUPType2SessionTransformedRoute{ 1377 Rd: rd, 1378 EndpointAddressLength: uint32(r.EndpointAddressLength), 1379 EndpointAddress: r.EndpointAddress.String(), 1380 Teid: binary.BigEndian.Uint32(r.TEID.AsSlice()), 1381 } 1382 nlri = ar 1383 } 1384 } 1385 1386 an, _ := apb.New(nlri) 1387 return an, nil 1388 } 1389 1390 func MarshalNLRIs(values []bgp.AddrPrefixInterface) ([]*apb.Any, error) { 1391 nlris := make([]*apb.Any, 0, len(values)) 1392 for _, value := range values { 1393 nlri, err := MarshalNLRI(value) 1394 if err != nil { 1395 return nil, err 1396 } 1397 nlris = append(nlris, nlri) 1398 } 1399 return nlris, nil 1400 } 1401 1402 func UnmarshalNLRI(rf bgp.RouteFamily, an *apb.Any) (bgp.AddrPrefixInterface, error) { 1403 var nlri bgp.AddrPrefixInterface 1404 1405 value, err := an.UnmarshalNew() 1406 if err != nil { 1407 return nil, fmt.Errorf("failed to unmarshal nlri: %s", err) 1408 } 1409 1410 switch v := value.(type) { 1411 case *api.IPAddressPrefix: 1412 switch rf { 1413 case bgp.RF_IPv4_UC: 1414 nlri = bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix) 1415 case bgp.RF_IPv6_UC: 1416 nlri = bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix) 1417 } 1418 case *api.LabeledIPAddressPrefix: 1419 switch rf { 1420 case bgp.RF_IPv4_MPLS: 1421 nlri = bgp.NewLabeledIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) 1422 case bgp.RF_IPv6_MPLS: 1423 nlri = bgp.NewLabeledIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) 1424 } 1425 case *api.EncapsulationNLRI: 1426 switch rf { 1427 case bgp.RF_IPv4_ENCAP: 1428 nlri = bgp.NewEncapNLRI(v.Address) 1429 case bgp.RF_IPv6_ENCAP: 1430 nlri = bgp.NewEncapv6NLRI(v.Address) 1431 } 1432 case *api.VPLSNLRI: 1433 if rf == bgp.RF_VPLS { 1434 rd, err := UnmarshalRD(v.Rd) 1435 if err != nil { 1436 return nil, err 1437 } 1438 nlri = bgp.NewVPLSNLRI( 1439 rd, 1440 uint16(v.VeId), 1441 uint16(v.VeBlockOffset), 1442 uint16(v.VeBlockSize), 1443 v.LabelBlockBase) 1444 } 1445 case *api.EVPNEthernetAutoDiscoveryRoute: 1446 if rf == bgp.RF_EVPN { 1447 rd, err := UnmarshalRD(v.Rd) 1448 if err != nil { 1449 return nil, err 1450 } 1451 esi, err := unmarshalESI(v.Esi) 1452 if err != nil { 1453 return nil, err 1454 } 1455 nlri = bgp.NewEVPNEthernetAutoDiscoveryRoute(rd, *esi, v.EthernetTag, v.Label) 1456 } 1457 case *api.EVPNMACIPAdvertisementRoute: 1458 if rf == bgp.RF_EVPN { 1459 rd, err := UnmarshalRD(v.Rd) 1460 if err != nil { 1461 return nil, err 1462 } 1463 esi, err := unmarshalESI(v.Esi) 1464 if err != nil { 1465 return nil, err 1466 } 1467 nlri = bgp.NewEVPNMacIPAdvertisementRoute(rd, *esi, v.EthernetTag, v.MacAddress, v.IpAddress, v.Labels) 1468 } 1469 case *api.EVPNInclusiveMulticastEthernetTagRoute: 1470 if rf == bgp.RF_EVPN { 1471 rd, err := UnmarshalRD(v.Rd) 1472 if err != nil { 1473 return nil, err 1474 } 1475 nlri = bgp.NewEVPNMulticastEthernetTagRoute(rd, v.EthernetTag, v.IpAddress) 1476 } 1477 case *api.EVPNEthernetSegmentRoute: 1478 if rf == bgp.RF_EVPN { 1479 rd, err := UnmarshalRD(v.Rd) 1480 if err != nil { 1481 return nil, err 1482 } 1483 esi, err := unmarshalESI(v.Esi) 1484 if err != nil { 1485 return nil, err 1486 } 1487 nlri = bgp.NewEVPNEthernetSegmentRoute(rd, *esi, v.IpAddress) 1488 } 1489 case *api.EVPNIPPrefixRoute: 1490 if rf == bgp.RF_EVPN { 1491 rd, err := UnmarshalRD(v.Rd) 1492 if err != nil { 1493 return nil, err 1494 } 1495 esi, err := unmarshalESI(v.Esi) 1496 if err != nil { 1497 return nil, err 1498 } 1499 nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label) 1500 } 1501 case *api.SRPolicyNLRI: 1502 switch rf { 1503 case bgp.RF_SR_POLICY_IPv4: 1504 nlri = bgp.NewSRPolicyIPv4(v.Length, v.Distinguisher, v.Color, v.Endpoint) 1505 case bgp.RF_SR_POLICY_IPv6: 1506 nlri = bgp.NewSRPolicyIPv6(v.Length, v.Distinguisher, v.Color, v.Endpoint) 1507 } 1508 case *api.LabeledVPNIPAddressPrefix: 1509 rd, err := UnmarshalRD(v.Rd) 1510 if err != nil { 1511 return nil, err 1512 } 1513 switch rf { 1514 case bgp.RF_IPv4_VPN: 1515 nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) 1516 case bgp.RF_IPv6_VPN: 1517 nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) 1518 } 1519 case *api.RouteTargetMembershipNLRI: 1520 rt, err := UnmarshalRT(v.Rt) 1521 if err != nil { 1522 return nil, err 1523 } 1524 nlri = bgp.NewRouteTargetMembershipNLRI(v.Asn, rt) 1525 case *api.FlowSpecNLRI: 1526 rules, err := UnmarshalFlowSpecRules(v.Rules) 1527 if err != nil { 1528 return nil, err 1529 } 1530 switch rf { 1531 case bgp.RF_FS_IPv4_UC: 1532 nlri = bgp.NewFlowSpecIPv4Unicast(rules) 1533 case bgp.RF_FS_IPv6_UC: 1534 nlri = bgp.NewFlowSpecIPv6Unicast(rules) 1535 } 1536 case *api.VPNFlowSpecNLRI: 1537 rd, err := UnmarshalRD(v.Rd) 1538 if err != nil { 1539 return nil, err 1540 } 1541 rules, err := UnmarshalFlowSpecRules(v.Rules) 1542 if err != nil { 1543 return nil, err 1544 } 1545 switch rf { 1546 case bgp.RF_FS_IPv4_VPN: 1547 nlri = bgp.NewFlowSpecIPv4VPN(rd, rules) 1548 case bgp.RF_FS_IPv6_VPN: 1549 nlri = bgp.NewFlowSpecIPv6VPN(rd, rules) 1550 case bgp.RF_FS_L2_VPN: 1551 nlri = bgp.NewFlowSpecL2VPN(rd, rules) 1552 } 1553 case *api.MUPInterworkSegmentDiscoveryRoute: 1554 rd, err := UnmarshalRD(v.Rd) 1555 if err != nil { 1556 return nil, err 1557 } 1558 prefix, err := netip.ParsePrefix(v.Prefix) 1559 if err != nil { 1560 return nil, err 1561 } 1562 nlri = bgp.NewMUPInterworkSegmentDiscoveryRoute(rd, prefix) 1563 case *api.MUPDirectSegmentDiscoveryRoute: 1564 rd, err := UnmarshalRD(v.Rd) 1565 if err != nil { 1566 return nil, err 1567 } 1568 address, err := netip.ParseAddr(v.Address) 1569 if err != nil { 1570 return nil, err 1571 } 1572 nlri = bgp.NewMUPDirectSegmentDiscoveryRoute(rd, address) 1573 case *api.MUPType1SessionTransformedRoute: 1574 rd, err := UnmarshalRD(v.Rd) 1575 if err != nil { 1576 return nil, err 1577 } 1578 prefix, err := netip.ParsePrefix(v.Prefix) 1579 if err != nil { 1580 return nil, err 1581 } 1582 ea, err := netip.ParseAddr(v.EndpointAddress) 1583 if err != nil { 1584 return nil, err 1585 } 1586 b := make([]byte, 4) 1587 binary.BigEndian.PutUint32(b, v.Teid) 1588 teid, ok := netip.AddrFromSlice(b) 1589 if !ok { 1590 return nil, fmt.Errorf("invalid teid: %x", v.Teid) 1591 } 1592 var sa *netip.Addr 1593 if v.SourceAddressLength > 0 && v.SourceAddress != "" { 1594 a, err := netip.ParseAddr(v.SourceAddress) 1595 if err != nil { 1596 return nil, err 1597 } 1598 sa = &a 1599 } 1600 nlri = bgp.NewMUPType1SessionTransformedRoute(rd, prefix, teid, uint8(v.Qfi), ea, sa) 1601 case *api.MUPType2SessionTransformedRoute: 1602 rd, err := UnmarshalRD(v.Rd) 1603 if err != nil { 1604 return nil, err 1605 } 1606 ea, err := netip.ParseAddr(v.EndpointAddress) 1607 if err != nil { 1608 return nil, err 1609 } 1610 b := make([]byte, 4) 1611 binary.BigEndian.PutUint32(b, v.Teid) 1612 teid, ok := netip.AddrFromSlice(b) 1613 if !ok { 1614 return nil, fmt.Errorf("invalid teid: %x", v.Teid) 1615 } 1616 nlri = bgp.NewMUPType2SessionTransformedRoute(rd, uint8(v.EndpointAddressLength), ea, teid) 1617 case *api.LsAddrPrefix: 1618 unmarshaledNlri, _ := v.Nlri.UnmarshalNew() 1619 switch tp := unmarshaledNlri.(type) { 1620 case *api.LsNodeNLRI: 1621 lnd, err := UnmarshalLsNodeDescriptor(tp.LocalNode) 1622 if err != nil { 1623 return nil, err 1624 } 1625 lndTLV := bgp.NewLsTLVNodeDescriptor(lnd, bgp.LS_TLV_LOCAL_NODE_DESC) 1626 nlri = &bgp.LsAddrPrefix{ 1627 Type: bgp.LS_NLRI_TYPE_NODE, 1628 Length: uint16(v.Length), 1629 NLRI: &bgp.LsNodeNLRI{ 1630 LocalNodeDesc: &lndTLV, 1631 LsNLRI: bgp.LsNLRI{ 1632 NLRIType: bgp.LsNLRIType(v.Type), 1633 Length: uint16(v.Length), 1634 ProtocolID: bgp.LsProtocolID(v.ProtocolId), 1635 Identifier: v.Identifier, 1636 }, 1637 }, 1638 } 1639 case *api.LsLinkNLRI: 1640 lnd, err := UnmarshalLsNodeDescriptor(tp.LocalNode) 1641 if err != nil { 1642 return nil, err 1643 } 1644 lndTLV := bgp.NewLsTLVNodeDescriptor(lnd, bgp.LS_TLV_LOCAL_NODE_DESC) 1645 1646 rnd, err := UnmarshalLsNodeDescriptor(tp.RemoteNode) 1647 if err != nil { 1648 return nil, err 1649 } 1650 rndTLV := bgp.NewLsTLVNodeDescriptor(rnd, bgp.LS_TLV_REMOTE_NODE_DESC) 1651 1652 ld, err := UnmarshalLsLinkDescriptor(tp.LinkDescriptor) 1653 if err != nil { 1654 return nil, err 1655 } 1656 ldSubTLVs := bgp.NewLsLinkTLVs(ld) 1657 1658 nlri = &bgp.LsAddrPrefix{ 1659 Type: bgp.LS_NLRI_TYPE_LINK, 1660 Length: uint16(v.Length), 1661 NLRI: &bgp.LsLinkNLRI{ 1662 LocalNodeDesc: &lndTLV, 1663 RemoteNodeDesc: &rndTLV, 1664 LinkDesc: ldSubTLVs, 1665 LsNLRI: bgp.LsNLRI{ 1666 NLRIType: bgp.LsNLRIType(v.Type), 1667 Length: uint16(v.Length), 1668 ProtocolID: bgp.LsProtocolID(v.ProtocolId), 1669 Identifier: v.Identifier, 1670 }, 1671 }, 1672 } 1673 case *api.LsPrefixV4NLRI: 1674 lnd, err := UnmarshalLsNodeDescriptor(tp.LocalNode) 1675 if err != nil { 1676 return nil, err 1677 } 1678 lndTLV := bgp.NewLsTLVNodeDescriptor(lnd, bgp.LS_TLV_LOCAL_NODE_DESC) 1679 1680 pd, err := UnmarshalPrefixDescriptor(tp.PrefixDescriptor) 1681 if err != nil { 1682 return nil, err 1683 } 1684 pdSubTLVs := bgp.NewLsPrefixTLVs(pd) 1685 1686 nlri = &bgp.LsAddrPrefix{ 1687 Type: bgp.LS_NLRI_TYPE_PREFIX_IPV4, 1688 Length: uint16(v.Length), 1689 NLRI: &bgp.LsPrefixV4NLRI{ 1690 LocalNodeDesc: &lndTLV, 1691 PrefixDesc: pdSubTLVs, 1692 LsNLRI: bgp.LsNLRI{ 1693 NLRIType: bgp.LsNLRIType(v.Type), 1694 Length: uint16(v.Length), 1695 ProtocolID: bgp.LsProtocolID(v.ProtocolId), 1696 Identifier: v.Identifier, 1697 }, 1698 }, 1699 } 1700 1701 case *api.LsPrefixV6NLRI: 1702 lnd, err := UnmarshalLsNodeDescriptor(tp.LocalNode) 1703 if err != nil { 1704 return nil, err 1705 } 1706 lndTLV := bgp.NewLsTLVNodeDescriptor(lnd, bgp.LS_TLV_LOCAL_NODE_DESC) 1707 1708 pd, err := UnmarshalPrefixDescriptor(tp.PrefixDescriptor) 1709 if err != nil { 1710 return nil, err 1711 } 1712 pdSubTLVs := bgp.NewLsPrefixTLVs(pd) 1713 1714 nlri = &bgp.LsAddrPrefix{ 1715 Type: bgp.LS_NLRI_TYPE_PREFIX_IPV6, 1716 Length: uint16(v.Length), 1717 NLRI: &bgp.LsPrefixV6NLRI{ 1718 LocalNodeDesc: &lndTLV, 1719 PrefixDesc: pdSubTLVs, 1720 LsNLRI: bgp.LsNLRI{ 1721 NLRIType: bgp.LsNLRIType(v.Type), 1722 Length: uint16(v.Length), 1723 ProtocolID: bgp.LsProtocolID(v.ProtocolId), 1724 Identifier: v.Identifier, 1725 }, 1726 }, 1727 } 1728 1729 default: 1730 return nil, fmt.Errorf("unknown LS prefix type %v", tp) 1731 } 1732 } 1733 1734 if nlri == nil { 1735 return nil, fmt.Errorf("invalid nlri for %s family: %s", rf.String(), value) 1736 } 1737 1738 return nlri, nil 1739 } 1740 1741 func UnmarshalNLRIs(rf bgp.RouteFamily, values []*apb.Any) ([]bgp.AddrPrefixInterface, error) { 1742 nlris := make([]bgp.AddrPrefixInterface, 0, len(values)) 1743 for _, an := range values { 1744 nlri, err := UnmarshalNLRI(rf, an) 1745 if err != nil { 1746 return nil, err 1747 } 1748 nlris = append(nlris, nlri) 1749 } 1750 return nlris, nil 1751 } 1752 1753 func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) (*api.MpReachNLRIAttribute, error) { 1754 var nexthops []string 1755 if a.SAFI == bgp.SAFI_FLOW_SPEC_UNICAST || a.SAFI == bgp.SAFI_FLOW_SPEC_VPN { 1756 nexthops = nil 1757 } else { 1758 nexthops = []string{a.Nexthop.String()} 1759 if a.LinkLocalNexthop != nil && a.LinkLocalNexthop.IsLinkLocalUnicast() { 1760 nexthops = append(nexthops, a.LinkLocalNexthop.String()) 1761 } 1762 } 1763 n, err := MarshalNLRIs(a.Value) 1764 if err != nil { 1765 return nil, err 1766 } 1767 return &api.MpReachNLRIAttribute{ 1768 Family: ToApiFamily(a.AFI, a.SAFI), 1769 NextHops: nexthops, 1770 Nlris: n, 1771 }, nil 1772 } 1773 1774 func NewMpUnreachNLRIAttributeFromNative(a *bgp.PathAttributeMpUnreachNLRI) (*api.MpUnreachNLRIAttribute, error) { 1775 n, err := MarshalNLRIs(a.Value) 1776 if err != nil { 1777 return nil, err 1778 } 1779 return &api.MpUnreachNLRIAttribute{ 1780 Family: ToApiFamily(a.AFI, a.SAFI), 1781 Nlris: n, 1782 }, nil 1783 } 1784 1785 func MarshalRT(rt bgp.ExtendedCommunityInterface) (*apb.Any, error) { 1786 var r proto.Message 1787 switch v := rt.(type) { 1788 case *bgp.TwoOctetAsSpecificExtended: 1789 r = &api.TwoOctetAsSpecificExtended{ 1790 IsTransitive: true, 1791 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 1792 Asn: uint32(v.AS), 1793 LocalAdmin: uint32(v.LocalAdmin), 1794 } 1795 case *bgp.IPv4AddressSpecificExtended: 1796 r = &api.IPv4AddressSpecificExtended{ 1797 IsTransitive: true, 1798 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 1799 Address: v.IPv4.String(), 1800 LocalAdmin: uint32(v.LocalAdmin), 1801 } 1802 case *bgp.FourOctetAsSpecificExtended: 1803 r = &api.FourOctetAsSpecificExtended{ 1804 IsTransitive: true, 1805 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 1806 Asn: uint32(v.AS), 1807 LocalAdmin: uint32(v.LocalAdmin), 1808 } 1809 default: 1810 return nil, fmt.Errorf("invalid rt type to marshal: %v", rt) 1811 } 1812 a, _ := apb.New(r) 1813 return a, nil 1814 } 1815 1816 func MarshalRTs(values []bgp.ExtendedCommunityInterface) ([]*apb.Any, error) { 1817 rts := make([]*apb.Any, 0, len(values)) 1818 for _, rt := range values { 1819 r, err := MarshalRT(rt) 1820 if err != nil { 1821 return nil, err 1822 } 1823 rts = append(rts, r) 1824 } 1825 return rts, nil 1826 } 1827 1828 func UnmarshalRT(a *apb.Any) (bgp.ExtendedCommunityInterface, error) { 1829 value, err := a.UnmarshalNew() 1830 if err != nil { 1831 return nil, fmt.Errorf("failed to unmarshal route target: %s", err) 1832 } 1833 switch v := value.(type) { 1834 case *api.TwoOctetAsSpecificExtended: 1835 return bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.Asn), v.LocalAdmin, v.IsTransitive), nil 1836 case *api.IPv4AddressSpecificExtended: 1837 rt := bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 1838 if rt == nil { 1839 return nil, fmt.Errorf("invalid address for ipv4 address specific route target: %s", v.Address) 1840 } 1841 return rt, nil 1842 case *api.FourOctetAsSpecificExtended: 1843 return bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Asn, uint16(v.LocalAdmin), v.IsTransitive), nil 1844 } 1845 return nil, fmt.Errorf("invalid route target type: %s", a.TypeUrl) 1846 } 1847 1848 func UnmarshalRTs(values []*apb.Any) ([]bgp.ExtendedCommunityInterface, error) { 1849 rts := make([]bgp.ExtendedCommunityInterface, 0, len(values)) 1850 for _, an := range values { 1851 rt, err := UnmarshalRT(an) 1852 if err != nil { 1853 return nil, err 1854 } 1855 rts = append(rts, rt) 1856 } 1857 return rts, nil 1858 } 1859 1860 func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommunities) (*api.ExtendedCommunitiesAttribute, error) { 1861 communities := make([]*apb.Any, 0, len(a.Value)) 1862 for _, value := range a.Value { 1863 var community proto.Message 1864 switch v := value.(type) { 1865 case *bgp.TwoOctetAsSpecificExtended: 1866 community = &api.TwoOctetAsSpecificExtended{ 1867 IsTransitive: v.IsTransitive, 1868 SubType: uint32(v.SubType), 1869 Asn: uint32(v.AS), 1870 LocalAdmin: uint32(v.LocalAdmin), 1871 } 1872 case *bgp.IPv4AddressSpecificExtended: 1873 community = &api.IPv4AddressSpecificExtended{ 1874 IsTransitive: v.IsTransitive, 1875 SubType: uint32(v.SubType), 1876 Address: v.IPv4.String(), 1877 LocalAdmin: uint32(v.LocalAdmin), 1878 } 1879 case *bgp.FourOctetAsSpecificExtended: 1880 community = &api.FourOctetAsSpecificExtended{ 1881 IsTransitive: v.IsTransitive, 1882 SubType: uint32(v.SubType), 1883 Asn: uint32(v.AS), 1884 LocalAdmin: uint32(v.LocalAdmin), 1885 } 1886 case *bgp.ValidationExtended: 1887 community = &api.ValidationExtended{ 1888 State: uint32(v.State), 1889 } 1890 case *bgp.LinkBandwidthExtended: 1891 community = &api.LinkBandwidthExtended{ 1892 Asn: uint32(v.AS), 1893 Bandwidth: v.Bandwidth, 1894 } 1895 case *bgp.ColorExtended: 1896 community = &api.ColorExtended{ 1897 Color: v.Color, 1898 } 1899 case *bgp.EncapExtended: 1900 community = &api.EncapExtended{ 1901 TunnelType: uint32(v.TunnelType), 1902 } 1903 case *bgp.DefaultGatewayExtended: 1904 community = &api.DefaultGatewayExtended{} 1905 case *bgp.OpaqueExtended: 1906 community = &api.OpaqueExtended{ 1907 IsTransitive: v.IsTransitive, 1908 Value: v.Value, 1909 } 1910 case *bgp.ESILabelExtended: 1911 community = &api.ESILabelExtended{ 1912 IsSingleActive: v.IsSingleActive, 1913 Label: v.Label, 1914 } 1915 case *bgp.ESImportRouteTarget: 1916 community = &api.ESImportRouteTarget{ 1917 EsImport: v.ESImport.String(), 1918 } 1919 case *bgp.MacMobilityExtended: 1920 community = &api.MacMobilityExtended{ 1921 IsSticky: v.IsSticky, 1922 SequenceNum: v.Sequence, 1923 } 1924 case *bgp.RouterMacExtended: 1925 community = &api.RouterMacExtended{ 1926 Mac: v.Mac.String(), 1927 } 1928 case *bgp.TrafficRateExtended: 1929 community = &api.TrafficRateExtended{ 1930 Asn: uint32(v.AS), 1931 Rate: v.Rate, 1932 } 1933 case *bgp.TrafficActionExtended: 1934 community = &api.TrafficActionExtended{ 1935 Terminal: v.Terminal, 1936 Sample: v.Sample, 1937 } 1938 case *bgp.RedirectTwoOctetAsSpecificExtended: 1939 community = &api.RedirectTwoOctetAsSpecificExtended{ 1940 Asn: uint32(v.AS), 1941 LocalAdmin: v.LocalAdmin, 1942 } 1943 case *bgp.RedirectIPv4AddressSpecificExtended: 1944 community = &api.RedirectIPv4AddressSpecificExtended{ 1945 Address: v.IPv4.String(), 1946 LocalAdmin: uint32(v.LocalAdmin), 1947 } 1948 case *bgp.RedirectFourOctetAsSpecificExtended: 1949 community = &api.RedirectFourOctetAsSpecificExtended{ 1950 Asn: v.AS, 1951 LocalAdmin: uint32(v.LocalAdmin), 1952 } 1953 case *bgp.TrafficRemarkExtended: 1954 community = &api.TrafficRemarkExtended{ 1955 Dscp: uint32(v.DSCP), 1956 } 1957 case *bgp.MUPExtended: 1958 community = &api.MUPExtended{ 1959 SubType: uint32(v.SubType), 1960 SegmentId2: uint32(v.SegmentID2), 1961 SegmentId4: v.SegmentID4, 1962 } 1963 case *bgp.VPLSExtended: 1964 community = &api.VPLSExtended{ 1965 ControlFlags: uint32(v.ControlFlags), 1966 Mtu: uint32(v.MTU), 1967 } 1968 case *bgp.UnknownExtended: 1969 community = &api.UnknownExtended{ 1970 Type: uint32(v.Type), 1971 Value: v.Value, 1972 } 1973 default: 1974 return nil, fmt.Errorf("unsupported extended community: %v", value) 1975 } 1976 an, _ := apb.New(community) 1977 communities = append(communities, an) 1978 } 1979 return &api.ExtendedCommunitiesAttribute{ 1980 Communities: communities, 1981 }, nil 1982 } 1983 1984 func unmarshalExComm(a *api.ExtendedCommunitiesAttribute) (*bgp.PathAttributeExtendedCommunities, error) { 1985 communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) 1986 for _, an := range a.Communities { 1987 var community bgp.ExtendedCommunityInterface 1988 value, err := an.UnmarshalNew() 1989 if err != nil { 1990 return nil, fmt.Errorf("failed to unmarshal extended community: %s", err) 1991 } 1992 switch v := value.(type) { 1993 case *api.TwoOctetAsSpecificExtended: 1994 community = bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.Asn), v.LocalAdmin, v.IsTransitive) 1995 case *api.IPv4AddressSpecificExtended: 1996 community = bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 1997 case *api.FourOctetAsSpecificExtended: 1998 community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Asn, uint16(v.LocalAdmin), v.IsTransitive) 1999 case *api.ValidationExtended: 2000 community = bgp.NewValidationExtended(bgp.ValidationState(v.State)) 2001 case *api.LinkBandwidthExtended: 2002 community = bgp.NewLinkBandwidthExtended(uint16(v.Asn), v.Bandwidth) 2003 case *api.ColorExtended: 2004 community = bgp.NewColorExtended(v.Color) 2005 case *api.EncapExtended: 2006 community = bgp.NewEncapExtended(bgp.TunnelType(v.TunnelType)) 2007 case *api.DefaultGatewayExtended: 2008 community = bgp.NewDefaultGatewayExtended() 2009 case *api.OpaqueExtended: 2010 community = bgp.NewOpaqueExtended(v.IsTransitive, v.Value) 2011 case *api.ESILabelExtended: 2012 community = bgp.NewESILabelExtended(v.Label, v.IsSingleActive) 2013 case *api.ESImportRouteTarget: 2014 community = bgp.NewESImportRouteTarget(v.EsImport) 2015 case *api.MacMobilityExtended: 2016 community = bgp.NewMacMobilityExtended(v.SequenceNum, v.IsSticky) 2017 case *api.RouterMacExtended: 2018 community = bgp.NewRoutersMacExtended(v.Mac) 2019 case *api.TrafficRateExtended: 2020 community = bgp.NewTrafficRateExtended(uint16(v.Asn), v.Rate) 2021 case *api.TrafficActionExtended: 2022 community = bgp.NewTrafficActionExtended(v.Terminal, v.Sample) 2023 case *api.RedirectTwoOctetAsSpecificExtended: 2024 community = bgp.NewRedirectTwoOctetAsSpecificExtended(uint16(v.Asn), v.LocalAdmin) 2025 case *api.RedirectIPv4AddressSpecificExtended: 2026 community = bgp.NewRedirectIPv4AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) 2027 case *api.RedirectFourOctetAsSpecificExtended: 2028 community = bgp.NewRedirectFourOctetAsSpecificExtended(v.Asn, uint16(v.LocalAdmin)) 2029 case *api.TrafficRemarkExtended: 2030 community = bgp.NewTrafficRemarkExtended(uint8(v.Dscp)) 2031 case *api.MUPExtended: 2032 community = bgp.NewMUPExtended(uint16(v.SegmentId2), v.SegmentId4) 2033 case *api.VPLSExtended: 2034 community = bgp.NewVPLSExtended(uint8(v.ControlFlags), uint16(v.Mtu)) 2035 case *api.UnknownExtended: 2036 community = bgp.NewUnknownExtended(bgp.ExtendedCommunityAttrType(v.Type), v.Value) 2037 } 2038 if community == nil { 2039 return nil, fmt.Errorf("invalid extended community: %v", value) 2040 } 2041 communities = append(communities, community) 2042 } 2043 return bgp.NewPathAttributeExtendedCommunities(communities), nil 2044 } 2045 2046 func NewAs4PathAttributeFromNative(a *bgp.PathAttributeAs4Path) (*api.As4PathAttribute, error) { 2047 segments := make([]*api.AsSegment, 0, len(a.Value)) 2048 for _, param := range a.Value { 2049 segments = append(segments, &api.AsSegment{ 2050 Type: api.AsSegment_Type(param.Type), 2051 Numbers: param.AS, 2052 }) 2053 } 2054 return &api.As4PathAttribute{ 2055 Segments: segments, 2056 }, nil 2057 } 2058 2059 func NewAs4AggregatorAttributeFromNative(a *bgp.PathAttributeAs4Aggregator) (*api.As4AggregatorAttribute, error) { 2060 return &api.As4AggregatorAttribute{ 2061 Asn: a.Value.AS, 2062 Address: a.Value.Address.String(), 2063 }, nil 2064 } 2065 2066 func NewPmsiTunnelAttributeFromNative(a *bgp.PathAttributePmsiTunnel) (*api.PmsiTunnelAttribute, error) { 2067 var flags uint32 2068 if a.IsLeafInfoRequired { 2069 flags |= 0x01 2070 } 2071 id, _ := a.TunnelID.Serialize() 2072 return &api.PmsiTunnelAttribute{ 2073 Flags: flags, 2074 Type: uint32(a.TunnelType), 2075 Label: a.Label, 2076 Id: id, 2077 }, nil 2078 } 2079 2080 func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) (*api.TunnelEncapAttribute, error) { 2081 tlvs := make([]*api.TunnelEncapTLV, 0, len(a.Value)) 2082 for _, v := range a.Value { 2083 subTlvs := make([]*apb.Any, 0, len(v.Value)) 2084 for _, s := range v.Value { 2085 var subTlv proto.Message 2086 switch sv := s.(type) { 2087 case *bgp.TunnelEncapSubTLVEncapsulation: 2088 subTlv = &api.TunnelEncapSubTLVEncapsulation{ 2089 Key: sv.Key, 2090 Cookie: sv.Cookie, 2091 } 2092 case *bgp.TunnelEncapSubTLVProtocol: 2093 subTlv = &api.TunnelEncapSubTLVProtocol{ 2094 Protocol: uint32(sv.Protocol), 2095 } 2096 case *bgp.TunnelEncapSubTLVColor: 2097 subTlv = &api.TunnelEncapSubTLVColor{ 2098 Color: sv.Color, 2099 } 2100 case *bgp.TunnelEncapSubTLVEgressEndpoint: 2101 subTlv = &api.TunnelEncapSubTLVEgressEndpoint{ 2102 Address: sv.Address.String(), 2103 } 2104 case *bgp.TunnelEncapSubTLVUDPDestPort: 2105 subTlv = &api.TunnelEncapSubTLVUDPDestPort{ 2106 Port: uint32(sv.UDPDestPort), 2107 } 2108 case *bgp.TunnelEncapSubTLVUnknown: 2109 subTlv = &api.TunnelEncapSubTLVUnknown{ 2110 Type: uint32(sv.Type), 2111 Value: sv.Value, 2112 } 2113 case *bgp.TunnelEncapSubTLVSRBSID: 2114 t, err := MarshalSRBSID(sv) 2115 if err != nil { 2116 return nil, err 2117 } 2118 subTlv = &api.TunnelEncapSubTLVSRBindingSID{ 2119 Bsid: t} 2120 // TODO (sbezverk) Add processing of SRv6 Binding SID when it gets assigned ID 2121 case *bgp.TunnelEncapSubTLVSRCandidatePathName: 2122 subTlv = &api.TunnelEncapSubTLVSRCandidatePathName{ 2123 CandidatePathName: sv.CandidatePathName, 2124 } 2125 // TODO (sbezverk) Add processing of SR Policy name when it gets assigned ID 2126 case *bgp.TunnelEncapSubTLVSRENLP: 2127 subTlv = &api.TunnelEncapSubTLVSRENLP{ 2128 Flags: uint32(sv.Flags), 2129 Enlp: api.ENLPType(sv.ENLP), 2130 } 2131 case *bgp.TunnelEncapSubTLVSRPreference: 2132 subTlv = &api.TunnelEncapSubTLVSRPreference{ 2133 Flags: uint32(sv.Flags), 2134 Preference: sv.Preference, 2135 } 2136 case *bgp.TunnelEncapSubTLVSRPriority: 2137 subTlv = &api.TunnelEncapSubTLVSRPriority{ 2138 Priority: uint32(sv.Priority), 2139 } 2140 case *bgp.TunnelEncapSubTLVSRSegmentList: 2141 s, err := MarshalSRSegments(sv.Segments) 2142 if err != nil { 2143 return nil, err 2144 } 2145 subTlv = &api.TunnelEncapSubTLVSRSegmentList{ 2146 Weight: &api.SRWeight{ 2147 Flags: uint32(sv.Weight.Flags), 2148 Weight: uint32(sv.Weight.Weight), 2149 }, 2150 Segments: s, 2151 } 2152 } 2153 an, _ := apb.New(subTlv) 2154 subTlvs = append(subTlvs, an) 2155 } 2156 tlvs = append(tlvs, &api.TunnelEncapTLV{ 2157 Type: uint32(v.Type), 2158 Tlvs: subTlvs, 2159 }) 2160 } 2161 return &api.TunnelEncapAttribute{ 2162 Tlvs: tlvs, 2163 }, nil 2164 } 2165 2166 func NewIP6ExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeIP6ExtendedCommunities) (*api.IP6ExtendedCommunitiesAttribute, error) { 2167 communities := make([]*apb.Any, 0, len(a.Value)) 2168 for _, value := range a.Value { 2169 var community proto.Message 2170 switch v := value.(type) { 2171 case *bgp.IPv6AddressSpecificExtended: 2172 community = &api.IPv6AddressSpecificExtended{ 2173 IsTransitive: v.IsTransitive, 2174 SubType: uint32(v.SubType), 2175 Address: v.IPv6.String(), 2176 LocalAdmin: uint32(v.LocalAdmin), 2177 } 2178 case *bgp.RedirectIPv6AddressSpecificExtended: 2179 community = &api.RedirectIPv6AddressSpecificExtended{ 2180 Address: v.IPv6.String(), 2181 LocalAdmin: uint32(v.LocalAdmin), 2182 } 2183 default: 2184 return nil, fmt.Errorf("invalid ipv6 extended community: %v", value) 2185 } 2186 an, _ := apb.New(community) 2187 communities = append(communities, an) 2188 } 2189 return &api.IP6ExtendedCommunitiesAttribute{ 2190 Communities: communities, 2191 }, nil 2192 } 2193 2194 func NewAigpAttributeFromNative(a *bgp.PathAttributeAigp) (*api.AigpAttribute, error) { 2195 tlvs := make([]*apb.Any, 0, len(a.Values)) 2196 for _, value := range a.Values { 2197 var tlv proto.Message 2198 switch v := value.(type) { 2199 case *bgp.AigpTLVIgpMetric: 2200 tlv = &api.AigpTLVIGPMetric{ 2201 Metric: v.Metric, 2202 } 2203 case *bgp.AigpTLVDefault: 2204 tlv = &api.AigpTLVUnknown{ 2205 Type: uint32(v.Type()), 2206 Value: v.Value, 2207 } 2208 } 2209 an, _ := apb.New(tlv) 2210 tlvs = append(tlvs, an) 2211 } 2212 return &api.AigpAttribute{ 2213 Tlvs: tlvs, 2214 }, nil 2215 } 2216 2217 func NewLargeCommunitiesAttributeFromNative(a *bgp.PathAttributeLargeCommunities) (*api.LargeCommunitiesAttribute, error) { 2218 communities := make([]*api.LargeCommunity, 0, len(a.Values)) 2219 for _, v := range a.Values { 2220 communities = append(communities, &api.LargeCommunity{ 2221 GlobalAdmin: v.ASN, 2222 LocalData1: v.LocalData1, 2223 LocalData2: v.LocalData2, 2224 }) 2225 } 2226 return &api.LargeCommunitiesAttribute{ 2227 Communities: communities, 2228 }, nil 2229 } 2230 2231 func stringOrDefault(s *string) string { 2232 if s == nil { 2233 return "" 2234 } 2235 return *s 2236 } 2237 2238 func bytesOrDefault(b *[]byte) []byte { 2239 if b == nil { 2240 return []byte{} 2241 } 2242 return *b 2243 } 2244 2245 func ipOrDefault(ip *net.IP) string { 2246 if ip == nil { 2247 return "" 2248 } 2249 return ip.String() 2250 } 2251 2252 func uint32OrDefault(i *uint32) uint32 { 2253 if i == nil { 2254 return 0 2255 } 2256 return *i 2257 } 2258 2259 func float32OrDefault(f *float32) float32 { 2260 if f == nil { 2261 return 0.0 2262 } 2263 return *f 2264 } 2265 2266 func NewLsAttributeFromNative(a *bgp.PathAttributeLs) (*api.LsAttribute, error) { 2267 attr := a.Extract() 2268 2269 bgpPeerSegment := &api.LsAttributeBgpPeerSegment{} 2270 if attr.BgpPeerSegment.BgpPeerNodeSid != nil { 2271 bgpPeerSegment.BgpPeerNodeSid, _ = MarshalLsBgpPeerSegmentSid(attr.BgpPeerSegment.BgpPeerNodeSid) 2272 } 2273 if attr.BgpPeerSegment.BgpPeerAdjacencySid != nil { 2274 bgpPeerSegment.BgpPeerAdjacencySid, _ = MarshalLsBgpPeerSegmentSid(attr.BgpPeerSegment.BgpPeerAdjacencySid) 2275 } 2276 if attr.BgpPeerSegment.BgpPeerSetSid != nil { 2277 bgpPeerSegment.BgpPeerSetSid, _ = MarshalLsBgpPeerSegmentSid(attr.BgpPeerSegment.BgpPeerSetSid) 2278 } 2279 2280 apiAttr := &api.LsAttribute{ 2281 Node: &api.LsAttributeNode{ 2282 Name: stringOrDefault(attr.Node.Name), 2283 Opaque: bytesOrDefault(attr.Node.Opaque), 2284 IsisArea: bytesOrDefault(attr.Node.IsisArea), 2285 LocalRouterId: ipOrDefault(attr.Node.LocalRouterID), 2286 LocalRouterIdV6: ipOrDefault(attr.Node.LocalRouterIDv6), 2287 2288 SrAlgorithms: bytesOrDefault(attr.Node.SrAlgorithms), 2289 }, 2290 Link: &api.LsAttributeLink{ 2291 Name: stringOrDefault(attr.Link.Name), 2292 Opaque: bytesOrDefault(attr.Link.Opaque), 2293 LocalRouterId: ipOrDefault(attr.Link.LocalRouterID), 2294 LocalRouterIdV6: ipOrDefault(attr.Link.LocalRouterIDv6), 2295 RemoteRouterId: ipOrDefault(attr.Link.RemoteRouterID), 2296 RemoteRouterIdV6: ipOrDefault(attr.Link.RemoteRouterIDv6), 2297 AdminGroup: uint32OrDefault(attr.Link.AdminGroup), 2298 DefaultTeMetric: uint32OrDefault(attr.Link.DefaultTEMetric), 2299 IgpMetric: uint32OrDefault(attr.Link.IGPMetric), 2300 2301 Bandwidth: float32OrDefault(attr.Link.Bandwidth), 2302 ReservableBandwidth: float32OrDefault(attr.Link.ReservableBandwidth), 2303 SrAdjacencySid: uint32OrDefault(attr.Link.SrAdjacencySID), 2304 }, 2305 Prefix: &api.LsAttributePrefix{ 2306 Opaque: bytesOrDefault(attr.Prefix.Opaque), 2307 2308 SrPrefixSid: uint32OrDefault(attr.Prefix.SrPrefixSID), 2309 }, 2310 BgpPeerSegment: bgpPeerSegment, 2311 } 2312 2313 if attr.Node.Flags != nil { 2314 apiAttr.Node.Flags = &api.LsNodeFlags{ 2315 Overload: attr.Node.Flags.Overload, 2316 Attached: attr.Node.Flags.Attached, 2317 External: attr.Node.Flags.External, 2318 Abr: attr.Node.Flags.ABR, 2319 Router: attr.Node.Flags.Router, 2320 V6: attr.Node.Flags.V6, 2321 } 2322 } 2323 2324 if attr.Node.SrCapabilties != nil { 2325 apiAttr.Node.SrCapabilities = &api.LsSrCapabilities{ 2326 Ipv4Supported: attr.Node.SrCapabilties.IPv4Supported, 2327 Ipv6Supported: attr.Node.SrCapabilties.IPv6Supported, 2328 } 2329 2330 for _, r := range attr.Node.SrCapabilties.Ranges { 2331 apiAttr.Node.SrCapabilities.Ranges = append(apiAttr.Node.SrCapabilities.Ranges, &api.LsSrRange{ 2332 Begin: r.Begin, 2333 End: r.End, 2334 }) 2335 } 2336 } 2337 2338 if attr.Node.SrLocalBlock != nil { 2339 apiAttr.Node.SrLocalBlock = &api.LsSrLocalBlock{} 2340 for _, r := range attr.Node.SrLocalBlock.Ranges { 2341 apiAttr.Node.SrLocalBlock.Ranges = append(apiAttr.Node.SrLocalBlock.Ranges, &api.LsSrRange{ 2342 Begin: r.Begin, 2343 End: r.End, 2344 }) 2345 } 2346 } 2347 2348 if attr.Link.UnreservedBandwidth != nil { 2349 for _, f := range attr.Link.UnreservedBandwidth { 2350 apiAttr.Link.UnreservedBandwidth = append(apiAttr.Link.UnreservedBandwidth, f) 2351 } 2352 } 2353 2354 if attr.Link.Srlgs != nil { 2355 apiAttr.Link.Srlgs = append(apiAttr.Link.Srlgs, *attr.Link.Srlgs...) 2356 } 2357 2358 if attr.Prefix.IGPFlags != nil { 2359 apiAttr.Prefix.IgpFlags = &api.LsIGPFlags{ 2360 Down: attr.Prefix.IGPFlags.Down, 2361 NoUnicast: attr.Prefix.IGPFlags.NoUnicast, 2362 LocalAddress: attr.Prefix.IGPFlags.LocalAddress, 2363 PropagateNssa: attr.Prefix.IGPFlags.PropagateNSSA, 2364 } 2365 } 2366 2367 return apiAttr, nil 2368 } 2369 2370 func NewUnknownAttributeFromNative(a *bgp.PathAttributeUnknown) (*api.UnknownAttribute, error) { 2371 return &api.UnknownAttribute{ 2372 Flags: uint32(a.Flags), 2373 Type: uint32(a.Type), 2374 Value: a.Value, 2375 }, nil 2376 } 2377 2378 func MarshalPathAttributes(attrList []bgp.PathAttributeInterface) ([]*apb.Any, error) { 2379 anyList := make([]*apb.Any, 0, len(attrList)) 2380 for _, attr := range attrList { 2381 switch a := attr.(type) { 2382 case *bgp.PathAttributeOrigin: 2383 v, err := NewOriginAttributeFromNative(a) 2384 if err != nil { 2385 return nil, err 2386 } 2387 n, _ := apb.New(v) 2388 anyList = append(anyList, n) 2389 case *bgp.PathAttributeAsPath: 2390 v, err := NewAsPathAttributeFromNative(a) 2391 if err != nil { 2392 return nil, err 2393 } 2394 n, _ := apb.New(v) 2395 anyList = append(anyList, n) 2396 case *bgp.PathAttributeNextHop: 2397 v, err := NewNextHopAttributeFromNative(a) 2398 if err != nil { 2399 return nil, err 2400 } 2401 n, _ := apb.New(v) 2402 anyList = append(anyList, n) 2403 case *bgp.PathAttributeMultiExitDisc: 2404 v, err := NewMultiExitDiscAttributeFromNative(a) 2405 if err != nil { 2406 return nil, err 2407 } 2408 n, _ := apb.New(v) 2409 anyList = append(anyList, n) 2410 case *bgp.PathAttributeLocalPref: 2411 v, err := NewLocalPrefAttributeFromNative(a) 2412 if err != nil { 2413 return nil, err 2414 } 2415 n, _ := apb.New(v) 2416 anyList = append(anyList, n) 2417 case *bgp.PathAttributeAtomicAggregate: 2418 v, err := NewAtomicAggregateAttributeFromNative(a) 2419 if err != nil { 2420 return nil, err 2421 } 2422 n, _ := apb.New(v) 2423 anyList = append(anyList, n) 2424 case *bgp.PathAttributeAggregator: 2425 v, err := NewAggregatorAttributeFromNative(a) 2426 if err != nil { 2427 return nil, err 2428 } 2429 n, _ := apb.New(v) 2430 anyList = append(anyList, n) 2431 case *bgp.PathAttributeCommunities: 2432 v, err := NewCommunitiesAttributeFromNative(a) 2433 if err != nil { 2434 return nil, err 2435 } 2436 n, _ := apb.New(v) 2437 anyList = append(anyList, n) 2438 case *bgp.PathAttributeOriginatorId: 2439 v, err := NewOriginatorIdAttributeFromNative(a) 2440 if err != nil { 2441 return nil, err 2442 } 2443 n, _ := apb.New(v) 2444 anyList = append(anyList, n) 2445 case *bgp.PathAttributeClusterList: 2446 v, err := NewClusterListAttributeFromNative(a) 2447 if err != nil { 2448 return nil, err 2449 } 2450 n, _ := apb.New(v) 2451 anyList = append(anyList, n) 2452 case *bgp.PathAttributeMpReachNLRI: 2453 v, err := NewMpReachNLRIAttributeFromNative(a) 2454 if err != nil { 2455 return nil, err 2456 } 2457 n, _ := apb.New(v) 2458 anyList = append(anyList, n) 2459 case *bgp.PathAttributeMpUnreachNLRI: 2460 v, err := NewMpUnreachNLRIAttributeFromNative(a) 2461 if err != nil { 2462 return nil, err 2463 } 2464 n, _ := apb.New(v) 2465 anyList = append(anyList, n) 2466 case *bgp.PathAttributeExtendedCommunities: 2467 v, err := NewExtendedCommunitiesAttributeFromNative(a) 2468 if err != nil { 2469 return nil, err 2470 } 2471 n, _ := apb.New(v) 2472 anyList = append(anyList, n) 2473 case *bgp.PathAttributeAs4Path: 2474 v, err := NewAs4PathAttributeFromNative(a) 2475 if err != nil { 2476 return nil, err 2477 } 2478 n, _ := apb.New(v) 2479 anyList = append(anyList, n) 2480 case *bgp.PathAttributeAs4Aggregator: 2481 v, err := NewAs4AggregatorAttributeFromNative(a) 2482 if err != nil { 2483 return nil, err 2484 } 2485 n, _ := apb.New(v) 2486 anyList = append(anyList, n) 2487 case *bgp.PathAttributePmsiTunnel: 2488 v, err := NewPmsiTunnelAttributeFromNative(a) 2489 if err != nil { 2490 return nil, err 2491 } 2492 n, _ := apb.New(v) 2493 anyList = append(anyList, n) 2494 case *bgp.PathAttributeTunnelEncap: 2495 v, err := NewTunnelEncapAttributeFromNative(a) 2496 if err != nil { 2497 return nil, err 2498 } 2499 n, _ := apb.New(v) 2500 anyList = append(anyList, n) 2501 case *bgp.PathAttributeIP6ExtendedCommunities: 2502 v, err := NewIP6ExtendedCommunitiesAttributeFromNative(a) 2503 if err != nil { 2504 return nil, err 2505 } 2506 n, _ := apb.New(v) 2507 anyList = append(anyList, n) 2508 case *bgp.PathAttributeAigp: 2509 v, err := NewAigpAttributeFromNative(a) 2510 if err != nil { 2511 return nil, err 2512 } 2513 n, _ := apb.New(v) 2514 anyList = append(anyList, n) 2515 case *bgp.PathAttributeLargeCommunities: 2516 v, err := NewLargeCommunitiesAttributeFromNative(a) 2517 if err != nil { 2518 return nil, err 2519 } 2520 n, _ := apb.New(v) 2521 anyList = append(anyList, n) 2522 case *bgp.PathAttributeLs: 2523 v, err := NewLsAttributeFromNative(a) 2524 if err != nil { 2525 return nil, err 2526 } 2527 n, _ := apb.New(v) 2528 anyList = append(anyList, n) 2529 case *bgp.PathAttributePrefixSID: 2530 v, err := NewPrefixSIDAttributeFromNative(a) 2531 if err != nil { 2532 return nil, err 2533 } 2534 n, _ := apb.New(v) 2535 anyList = append(anyList, n) 2536 case *bgp.PathAttributeUnknown: 2537 v, err := NewUnknownAttributeFromNative(a) 2538 if err != nil { 2539 return nil, err 2540 } 2541 n, _ := apb.New(v) 2542 anyList = append(anyList, n) 2543 } 2544 } 2545 return anyList, nil 2546 } 2547 2548 func UnmarshalPathAttributes(values []*apb.Any) ([]bgp.PathAttributeInterface, error) { 2549 attrList := make([]bgp.PathAttributeInterface, 0, len(values)) 2550 typeMap := make(map[bgp.BGPAttrType]struct{}) 2551 for _, an := range values { 2552 attr, err := UnmarshalAttribute(an) 2553 if err != nil { 2554 return nil, err 2555 } 2556 if _, ok := typeMap[attr.GetType()]; ok { 2557 return nil, fmt.Errorf("duplicated path attribute type: %d", attr.GetType()) 2558 } 2559 typeMap[attr.GetType()] = struct{}{} 2560 attrList = append(attrList, attr) 2561 } 2562 return attrList, nil 2563 } 2564 2565 // MarshalSRBSID marshals SR Policy Binding SID Sub TLV structure 2566 func MarshalSRBSID(bsid *bgp.TunnelEncapSubTLVSRBSID) (*apb.Any, error) { 2567 var r proto.Message 2568 s := &api.SRBindingSID{ 2569 Sid: make([]byte, len(bsid.BSID.Value)), 2570 } 2571 copy(s.Sid, bsid.BSID.Value) 2572 s.SFlag = bsid.Flags&0x80 == 0x80 2573 s.IFlag = bsid.Flags&0x40 == 0x40 2574 r = s 2575 a, _ := apb.New(r) 2576 return a, nil 2577 } 2578 2579 // UnmarshalSRBSID unmarshals SR Policy Binding SID Sub TLV and returns native TunnelEncapSubTLVInterface interface 2580 func UnmarshalSRBSID(bsid *apb.Any) (bgp.TunnelEncapSubTLVInterface, error) { 2581 value, err := bsid.UnmarshalNew() 2582 if err != nil { 2583 return nil, fmt.Errorf("failed to unmarshal tunnel encap sub tlv: %s", err) 2584 } 2585 switch v := value.(type) { 2586 case *api.SRBindingSID: 2587 b, err := bgp.NewBSID(v.Sid) 2588 if err != nil { 2589 return nil, err 2590 } 2591 flags := uint8(0x0) 2592 if v.SFlag { 2593 flags += 0x80 2594 } 2595 if v.IFlag { 2596 flags += 0x40 2597 } 2598 return &bgp.TunnelEncapSubTLVSRBSID{ 2599 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 2600 Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID, 2601 Length: uint16(2 + b.Len()), 2602 }, 2603 BSID: b, 2604 Flags: flags, 2605 }, nil 2606 case *api.SRv6BindingSID: 2607 b, err := bgp.NewBSID(v.Sid) 2608 if err != nil { 2609 return nil, err 2610 } 2611 result := &bgp.TunnelEncapSubTLVSRv6BSID{ 2612 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 2613 Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID, 2614 Length: uint16(2 + b.Len()), 2615 }, 2616 Flags: 0, 2617 BSID: b, 2618 } 2619 2620 if v.EndpointBehaviorStructure != nil { 2621 result.EPBAS = &bgp.SRv6EndpointBehaviorStructure{ 2622 Behavior: bgp.SRBehavior(v.EndpointBehaviorStructure.Behavior), 2623 BlockLen: uint8(v.EndpointBehaviorStructure.BlockLen), 2624 NodeLen: uint8(v.EndpointBehaviorStructure.NodeLen), 2625 FuncLen: uint8(v.EndpointBehaviorStructure.FuncLen), 2626 ArgLen: uint8(v.EndpointBehaviorStructure.ArgLen), 2627 } 2628 } 2629 2630 return result, nil 2631 default: 2632 return nil, fmt.Errorf("unknown binding sid type %+v", v) 2633 } 2634 } 2635 2636 // MarshalSRSegments marshals a slice of SR Policy Segment List 2637 func MarshalSRSegments(segs []bgp.TunnelEncapSubTLVInterface) ([]*apb.Any, error) { 2638 anyList := make([]*apb.Any, 0, len(segs)) 2639 for _, seg := range segs { 2640 var r proto.Message 2641 switch s := seg.(type) { 2642 case *bgp.SegmentTypeA: 2643 r = &api.SegmentTypeA{ 2644 Label: s.Label, 2645 Flags: &api.SegmentFlags{ 2646 VFlag: s.Flags&0x80 == 0x80, 2647 AFlag: s.Flags&0x40 == 0x40, 2648 SFlag: s.Flags&0x20 == 0x20, 2649 BFlag: s.Flags&0x10 == 0x10, 2650 }, 2651 } 2652 case *bgp.SegmentTypeB: 2653 flags := &api.SegmentFlags{ 2654 VFlag: s.Flags&0x80 == 0x80, 2655 AFlag: s.Flags&0x40 == 0x40, 2656 SFlag: s.Flags&0x20 == 0x20, 2657 BFlag: s.Flags&0x10 == 0x10, 2658 } 2659 segment := &api.SegmentTypeB{ 2660 Flags: flags, 2661 Sid: s.SID, 2662 } 2663 if s.SRv6EBS != nil { 2664 segment.EndpointBehaviorStructure = &api.SRv6EndPointBehavior{ 2665 Behavior: api.SRv6Behavior(s.SRv6EBS.Behavior), 2666 BlockLen: uint32(s.SRv6EBS.BlockLen), 2667 NodeLen: uint32(s.SRv6EBS.NodeLen), 2668 FuncLen: uint32(s.SRv6EBS.FuncLen), 2669 ArgLen: uint32(s.SRv6EBS.ArgLen), 2670 } 2671 } 2672 r = segment 2673 default: 2674 // Unrecognize Segment type, skip it 2675 continue 2676 } 2677 a, _ := apb.New(r) 2678 anyList = append(anyList, a) 2679 } 2680 return anyList, nil 2681 } 2682 2683 // UnmarshalSRSegments unmarshals SR Policy Segments slice of structs 2684 func UnmarshalSRSegments(s []*apb.Any) ([]bgp.TunnelEncapSubTLVInterface, error) { 2685 if len(s) == 0 { 2686 return nil, nil 2687 } 2688 segments := make([]bgp.TunnelEncapSubTLVInterface, len(s)) 2689 for i := 0; i < len(s); i++ { 2690 value, err := s[i].UnmarshalNew() 2691 if err != nil { 2692 return nil, fmt.Errorf("failed to unmarshal SR Policy Segment: %s", err) 2693 } 2694 switch v := value.(type) { 2695 case *api.SegmentTypeA: 2696 seg := &bgp.SegmentTypeA{ 2697 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 2698 Type: bgp.EncapSubTLVType(bgp.TypeA), 2699 Length: 6, 2700 }, 2701 Label: v.Label, 2702 } 2703 if v.Flags.VFlag { 2704 seg.Flags += 0x80 2705 } 2706 if v.Flags.AFlag { 2707 seg.Flags += 0x40 2708 } 2709 if v.Flags.SFlag { 2710 seg.Flags += 0x20 2711 } 2712 if v.Flags.BFlag { 2713 seg.Flags += 0x10 2714 } 2715 segments[i] = seg 2716 case *api.SegmentTypeB: 2717 seg := &bgp.SegmentTypeB{ 2718 TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{ 2719 Type: bgp.EncapSubTLVType(bgp.TypeB), 2720 Length: 18, 2721 }, 2722 SID: v.GetSid(), 2723 } 2724 if v.Flags.VFlag { 2725 seg.Flags += 0x80 2726 } 2727 if v.Flags.AFlag { 2728 seg.Flags += 0x40 2729 } 2730 if v.Flags.SFlag { 2731 seg.Flags += 0x20 2732 } 2733 if v.Flags.BFlag { 2734 seg.Flags += 0x10 2735 } 2736 if v.EndpointBehaviorStructure != nil { 2737 ebs := v.GetEndpointBehaviorStructure() 2738 seg.SRv6EBS = &bgp.SRv6EndpointBehaviorStructure{ 2739 Behavior: bgp.SRBehavior(ebs.Behavior), 2740 BlockLen: uint8(ebs.BlockLen), 2741 NodeLen: uint8(ebs.NodeLen), 2742 FuncLen: uint8(ebs.FuncLen), 2743 ArgLen: uint8(ebs.ArgLen), 2744 } 2745 } 2746 segments[i] = seg 2747 } 2748 } 2749 return segments, nil 2750 } 2751 2752 func UnmarshalPrefixSID(psid *api.PrefixSID) (*bgp.PathAttributePrefixSID, error) { 2753 t := bgp.BGP_ATTR_TYPE_PREFIX_SID 2754 s := &bgp.PathAttributePrefixSID{ 2755 PathAttribute: bgp.PathAttribute{ 2756 Flags: bgp.PathAttrFlags[t], 2757 Type: t, 2758 }, 2759 TLVs: make([]bgp.PrefixSIDTLVInterface, 0), 2760 } 2761 for _, raw := range psid.Tlvs { 2762 tlv, err := raw.UnmarshalNew() 2763 if err != nil { 2764 return nil, err 2765 } 2766 switch v := tlv.(type) { 2767 case *api.SRv6L3ServiceTLV: 2768 tlvLength, tlvs, err := UnmarshalSubTLVs(v.SubTlvs) 2769 if err != nil { 2770 return nil, err 2771 } 2772 o := &bgp.SRv6L3ServiceAttribute{ 2773 TLV: bgp.TLV{ 2774 Type: bgp.TLVType(5), 2775 Length: tlvLength, 2776 }, 2777 } 2778 s.PathAttribute.Length += tlvLength 2779 // Storing Sub TLVs in a Service TLV 2780 o.SubTLVs = append(o.SubTLVs, tlvs...) 2781 // Adding Service TLV to Path Attribute TLV slice. 2782 s.TLVs = append(s.TLVs, o) 2783 default: 2784 return nil, fmt.Errorf("unknown or not implemented Prefix SID type: %+v", v) 2785 } 2786 } 2787 // Final Path Attribute Length is 3 bytes of the Path Attribute header longer 2788 s.PathAttribute.Length += 3 2789 return s, nil 2790 } 2791 2792 func UnmarshalSubTLVs(stlvs map[uint32]*api.SRv6TLV) (uint16, []bgp.PrefixSIDTLVInterface, error) { 2793 p := make([]bgp.PrefixSIDTLVInterface, 0, len(stlvs)) 2794 l := uint16(0) 2795 // v.SubTlvs is a map by sub tlv type and the value is a slice of sub tlvs of the specific type 2796 for t, tlv := range stlvs { 2797 switch t { 2798 case 1: 2799 // Sub TLV Type 1 is SRv6 Informational Sub TLV 2800 for _, stlvRaw := range tlv.Tlv { 2801 // Instantiating Information Sub TLV 2802 info := &bgp.SRv6InformationSubTLV{ 2803 SubTLV: bgp.SubTLV{ 2804 Type: bgp.SubTLVType(1), 2805 }, 2806 SubSubTLVs: make([]bgp.PrefixSIDTLVInterface, 0), 2807 } 2808 raw, err := stlvRaw.UnmarshalNew() 2809 if err != nil { 2810 return 0, nil, err 2811 } 2812 infoProto := raw.(*api.SRv6InformationSubTLV) 2813 info.SID = make([]byte, len(infoProto.Sid)) 2814 copy(info.SID, infoProto.Sid) 2815 // TODO Once RFC is published add processing of flags 2816 info.Flags = 0 2817 info.EndpointBehavior = uint16(infoProto.EndpointBehavior) 2818 var sstlvslength uint16 2819 var sstlvs []bgp.PrefixSIDTLVInterface 2820 if len(infoProto.SubSubTlvs) != 0 { 2821 // Processing Sub Sub TLVs 2822 var err error 2823 sstlvslength, sstlvs, err = UnmarshalSubSubTLVs(infoProto.SubSubTlvs) 2824 if err != nil { 2825 return 0, nil, err 2826 } 2827 info.SubSubTLVs = append(info.SubSubTLVs, sstlvs...) 2828 } 2829 // SRv6 Information Sub TLV length consists 1 byte Resrved2, 16 bytes SID, 1 byte flags, 2 bytes Endpoint Behavior 2830 // 1 byte Reserved3 and length of Sub Sub TLVs 2831 info.SubTLV.Length = 1 + 16 + 1 + 2 + 1 + sstlvslength 2832 // For total Prefix SID TLV length, adding 3 bytes of the TLV header + 1 byte of Reserved1 2833 l += info.SubTLV.Length + 4 2834 p = append(p, info) 2835 } 2836 default: 2837 return 0, nil, fmt.Errorf("unknown or not implemented Prefix SID Sub TLV type: %d", t) 2838 } 2839 } 2840 2841 return l, p, nil 2842 } 2843 2844 func UnmarshalSubSubTLVs(stlvs map[uint32]*api.SRv6TLV) (uint16, []bgp.PrefixSIDTLVInterface, error) { 2845 p := make([]bgp.PrefixSIDTLVInterface, 0) 2846 l := uint16(0) 2847 // v.SubTlvs is a map by sub tlv type and the value is a slice of sub tlvs of the specific type 2848 for t, tlv := range stlvs { 2849 switch t { 2850 case 1: 2851 // Sub Sub TLV Type 1 is SRv6 Structure Sub Sub TLV 2852 for _, stlvRaw := range tlv.Tlv { 2853 // Instantiating Information Sub TLV 2854 structure := &bgp.SRv6SIDStructureSubSubTLV{ 2855 SubSubTLV: bgp.SubSubTLV{ 2856 Type: bgp.SubSubTLVType(1), 2857 Length: 6, 2858 }, 2859 } 2860 raw, err := stlvRaw.UnmarshalNew() 2861 if err != nil { 2862 return 0, nil, err 2863 } 2864 structureProto := raw.(*api.SRv6StructureSubSubTLV) 2865 structure.LocatorBlockLength = uint8(structureProto.LocatorBlockLength) 2866 structure.LocatorNodeLength = uint8(structureProto.LocatorNodeLength) 2867 structure.FunctionLength = uint8(structureProto.FunctionLength) 2868 structure.ArgumentLength = uint8(structureProto.ArgumentLength) 2869 structure.TranspositionLength = uint8(structureProto.TranspositionLength) 2870 structure.TranspositionOffset = uint8(structureProto.TranspositionOffset) 2871 2872 // SRv6 Structure Sub Sub TLV length consists of header 3 bytes, 6 bytes of value 2873 l += 3 + 6 2874 p = append(p, structure) 2875 } 2876 default: 2877 return 0, nil, fmt.Errorf("unknown or not implemented Prefix SID Sub TLV type: %d", t) 2878 } 2879 } 2880 2881 return l, p, nil 2882 }