github.com/osrg/gobgp@v2.0.0+incompatible/internal/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 "errors" 20 "fmt" 21 "net" 22 23 "github.com/golang/protobuf/proto" 24 "github.com/golang/protobuf/ptypes" 25 "github.com/golang/protobuf/ptypes/any" 26 api "github.com/osrg/gobgp/api" 27 "github.com/osrg/gobgp/pkg/packet/bgp" 28 log "github.com/sirupsen/logrus" 29 ) 30 31 func UnmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) { 32 var value ptypes.DynamicAny 33 if err := ptypes.UnmarshalAny(an, &value); err != nil { 34 return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) 35 } 36 switch a := value.Message.(type) { 37 case *api.OriginAttribute: 38 return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil 39 case *api.AsPathAttribute: 40 params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) 41 for _, segment := range a.Segments { 42 params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) 43 } 44 return bgp.NewPathAttributeAsPath(params), nil 45 case *api.NextHopAttribute: 46 nexthop := net.ParseIP(a.NextHop).To4() 47 if nexthop == nil { 48 return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) 49 } 50 return bgp.NewPathAttributeNextHop(a.NextHop), nil 51 case *api.MultiExitDiscAttribute: 52 return bgp.NewPathAttributeMultiExitDisc(a.Med), nil 53 case *api.LocalPrefAttribute: 54 return bgp.NewPathAttributeLocalPref(a.LocalPref), nil 55 case *api.AtomicAggregateAttribute: 56 return bgp.NewPathAttributeAtomicAggregate(), nil 57 case *api.AggregatorAttribute: 58 if net.ParseIP(a.Address).To4() == nil { 59 return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) 60 } 61 return bgp.NewPathAttributeAggregator(a.As, a.Address), nil 62 case *api.CommunitiesAttribute: 63 return bgp.NewPathAttributeCommunities(a.Communities), nil 64 case *api.OriginatorIdAttribute: 65 if net.ParseIP(a.Id).To4() == nil { 66 return nil, fmt.Errorf("invalid originator id: %s", a.Id) 67 } 68 return bgp.NewPathAttributeOriginatorId(a.Id), nil 69 case *api.ClusterListAttribute: 70 for _, id := range a.Ids { 71 if net.ParseIP(id).To4() == nil { 72 return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) 73 } 74 } 75 return bgp.NewPathAttributeClusterList(a.Ids), nil 76 } 77 return nil, errors.New("unexpected object") 78 } 79 80 func NewOriginAttributeFromNative(a *bgp.PathAttributeOrigin) *api.OriginAttribute { 81 return &api.OriginAttribute{ 82 Origin: uint32(a.Value), 83 } 84 } 85 86 func NewAsPathAttributeFromNative(a *bgp.PathAttributeAsPath) *api.AsPathAttribute { 87 segments := make([]*api.AsSegment, 0, len(a.Value)) 88 for _, param := range a.Value { 89 segments = append(segments, &api.AsSegment{ 90 Type: uint32(param.GetType()), 91 Numbers: param.GetAS(), 92 }) 93 } 94 return &api.AsPathAttribute{ 95 Segments: segments, 96 } 97 } 98 99 func NewNextHopAttributeFromNative(a *bgp.PathAttributeNextHop) *api.NextHopAttribute { 100 return &api.NextHopAttribute{ 101 NextHop: a.Value.String(), 102 } 103 } 104 105 func NewMultiExitDiscAttributeFromNative(a *bgp.PathAttributeMultiExitDisc) *api.MultiExitDiscAttribute { 106 return &api.MultiExitDiscAttribute{ 107 Med: a.Value, 108 } 109 } 110 111 func NewLocalPrefAttributeFromNative(a *bgp.PathAttributeLocalPref) *api.LocalPrefAttribute { 112 return &api.LocalPrefAttribute{ 113 LocalPref: a.Value, 114 } 115 } 116 117 func NewAtomicAggregateAttributeFromNative(a *bgp.PathAttributeAtomicAggregate) *api.AtomicAggregateAttribute { 118 return &api.AtomicAggregateAttribute{} 119 } 120 121 func NewAggregatorAttributeFromNative(a *bgp.PathAttributeAggregator) *api.AggregatorAttribute { 122 return &api.AggregatorAttribute{ 123 As: a.Value.AS, 124 Address: a.Value.Address.String(), 125 } 126 } 127 128 func NewCommunitiesAttributeFromNative(a *bgp.PathAttributeCommunities) *api.CommunitiesAttribute { 129 return &api.CommunitiesAttribute{ 130 Communities: a.Value, 131 } 132 } 133 134 func NewOriginatorIdAttributeFromNative(a *bgp.PathAttributeOriginatorId) *api.OriginatorIdAttribute { 135 return &api.OriginatorIdAttribute{ 136 Id: a.Value.String(), 137 } 138 } 139 140 func NewClusterListAttributeFromNative(a *bgp.PathAttributeClusterList) *api.ClusterListAttribute { 141 ids := make([]string, 0, len(a.Value)) 142 for _, id := range a.Value { 143 ids = append(ids, id.String()) 144 } 145 return &api.ClusterListAttribute{ 146 Ids: ids, 147 } 148 } 149 150 func MarshalRD(rd bgp.RouteDistinguisherInterface) *any.Any { 151 var r proto.Message 152 switch v := rd.(type) { 153 case *bgp.RouteDistinguisherTwoOctetAS: 154 r = &api.RouteDistinguisherTwoOctetAS{ 155 Admin: uint32(v.Admin), 156 Assigned: v.Assigned, 157 } 158 case *bgp.RouteDistinguisherIPAddressAS: 159 r = &api.RouteDistinguisherIPAddress{ 160 Admin: v.Admin.String(), 161 Assigned: uint32(v.Assigned), 162 } 163 case *bgp.RouteDistinguisherFourOctetAS: 164 r = &api.RouteDistinguisherFourOctetAS{ 165 Admin: v.Admin, 166 Assigned: uint32(v.Assigned), 167 } 168 default: 169 log.WithFields(log.Fields{ 170 "Topic": "protobuf", 171 "RD": rd, 172 }).Warn("invalid rd type to marshal") 173 return nil 174 } 175 a, _ := ptypes.MarshalAny(r) 176 return a 177 } 178 179 func UnmarshalRD(a *any.Any) (bgp.RouteDistinguisherInterface, error) { 180 var value ptypes.DynamicAny 181 if err := ptypes.UnmarshalAny(a, &value); err != nil { 182 return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) 183 } 184 switch v := value.Message.(type) { 185 case *api.RouteDistinguisherTwoOctetAS: 186 return bgp.NewRouteDistinguisherTwoOctetAS(uint16(v.Admin), v.Assigned), nil 187 case *api.RouteDistinguisherIPAddress: 188 rd := bgp.NewRouteDistinguisherIPAddressAS(v.Admin, uint16(v.Assigned)) 189 if rd == nil { 190 return nil, fmt.Errorf("invalid address for route distinguisher: %s", v.Admin) 191 } 192 return rd, nil 193 case *api.RouteDistinguisherFourOctetAS: 194 return bgp.NewRouteDistinguisherFourOctetAS(v.Admin, uint16(v.Assigned)), nil 195 } 196 return nil, fmt.Errorf("invalid route distinguisher type: %s", a.TypeUrl) 197 } 198 199 func NewEthernetSegmentIdentifierFromNative(a *bgp.EthernetSegmentIdentifier) *api.EthernetSegmentIdentifier { 200 return &api.EthernetSegmentIdentifier{ 201 Type: uint32(a.Type), 202 Value: a.Value, 203 } 204 } 205 206 func unmarshalESI(a *api.EthernetSegmentIdentifier) (*bgp.EthernetSegmentIdentifier, error) { 207 return &bgp.EthernetSegmentIdentifier{ 208 Type: bgp.ESIType(a.Type), 209 Value: a.Value, 210 }, nil 211 } 212 213 func MarshalFlowSpecRules(values []bgp.FlowSpecComponentInterface) []*any.Any { 214 rules := make([]*any.Any, 0, len(values)) 215 for _, value := range values { 216 var rule proto.Message 217 switch v := value.(type) { 218 case *bgp.FlowSpecDestinationPrefix: 219 rule = &api.FlowSpecIPPrefix{ 220 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), 221 PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), 222 Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), 223 } 224 case *bgp.FlowSpecSourcePrefix: 225 rule = &api.FlowSpecIPPrefix{ 226 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), 227 PrefixLen: uint32(v.Prefix.(*bgp.IPAddrPrefix).Length), 228 Prefix: v.Prefix.(*bgp.IPAddrPrefix).Prefix.String(), 229 } 230 case *bgp.FlowSpecDestinationPrefix6: 231 rule = &api.FlowSpecIPPrefix{ 232 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_PREFIX), 233 PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), 234 Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), 235 Offset: uint32(v.Offset), 236 } 237 case *bgp.FlowSpecSourcePrefix6: 238 rule = &api.FlowSpecIPPrefix{ 239 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_PREFIX), 240 PrefixLen: uint32(v.Prefix.(*bgp.IPv6AddrPrefix).Length), 241 Prefix: v.Prefix.(*bgp.IPv6AddrPrefix).Prefix.String(), 242 Offset: uint32(v.Offset), 243 } 244 case *bgp.FlowSpecSourceMac: 245 rule = &api.FlowSpecMAC{ 246 Type: uint32(bgp.FLOW_SPEC_TYPE_SRC_MAC), 247 Address: v.Mac.String(), 248 } 249 case *bgp.FlowSpecDestinationMac: 250 rule = &api.FlowSpecMAC{ 251 Type: uint32(bgp.FLOW_SPEC_TYPE_DST_MAC), 252 Address: v.Mac.String(), 253 } 254 case *bgp.FlowSpecComponent: 255 items := make([]*api.FlowSpecComponentItem, 0, len(v.Items)) 256 for _, i := range v.Items { 257 items = append(items, &api.FlowSpecComponentItem{ 258 Op: uint32(i.Op), 259 Value: i.Value, 260 }) 261 } 262 rule = &api.FlowSpecComponent{ 263 Type: uint32(v.Type()), 264 Items: items, 265 } 266 } 267 a, _ := ptypes.MarshalAny(rule) 268 rules = append(rules, a) 269 } 270 return rules 271 } 272 273 func UnmarshalFlowSpecRules(values []*any.Any) ([]bgp.FlowSpecComponentInterface, error) { 274 rules := make([]bgp.FlowSpecComponentInterface, 0, len(values)) 275 for _, an := range values { 276 var rule bgp.FlowSpecComponentInterface 277 var value ptypes.DynamicAny 278 if err := ptypes.UnmarshalAny(an, &value); err != nil { 279 return nil, fmt.Errorf("failed to unmarshal flow spec component: %s", err) 280 } 281 switch v := value.Message.(type) { 282 case *api.FlowSpecIPPrefix: 283 typ := bgp.BGPFlowSpecType(v.Type) 284 isIPv4 := net.ParseIP(v.Prefix).To4() != nil 285 switch { 286 case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && isIPv4: 287 rule = bgp.NewFlowSpecDestinationPrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) 288 case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && isIPv4: 289 rule = bgp.NewFlowSpecSourcePrefix(bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix)) 290 case typ == bgp.FLOW_SPEC_TYPE_DST_PREFIX && !isIPv4: 291 rule = bgp.NewFlowSpecDestinationPrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) 292 case typ == bgp.FLOW_SPEC_TYPE_SRC_PREFIX && !isIPv4: 293 rule = bgp.NewFlowSpecSourcePrefix6(bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix), uint8(v.Offset)) 294 } 295 case *api.FlowSpecMAC: 296 typ := bgp.BGPFlowSpecType(v.Type) 297 mac, err := net.ParseMAC(v.Address) 298 if err != nil { 299 return nil, fmt.Errorf("invalid mac address for %s flow spec component: %s", typ.String(), v.Address) 300 } 301 switch typ { 302 case bgp.FLOW_SPEC_TYPE_SRC_MAC: 303 rule = bgp.NewFlowSpecSourceMac(mac) 304 case bgp.FLOW_SPEC_TYPE_DST_MAC: 305 rule = bgp.NewFlowSpecDestinationMac(mac) 306 } 307 case *api.FlowSpecComponent: 308 items := make([]*bgp.FlowSpecComponentItem, 0, len(v.Items)) 309 for _, item := range v.Items { 310 items = append(items, bgp.NewFlowSpecComponentItem(uint8(item.Op), item.Value)) 311 } 312 rule = bgp.NewFlowSpecComponent(bgp.BGPFlowSpecType(v.Type), items) 313 } 314 if rule == nil { 315 return nil, fmt.Errorf("invalid flow spec component: %v", value.Message) 316 } 317 rules = append(rules, rule) 318 } 319 return rules, nil 320 } 321 322 func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any { 323 var nlri proto.Message 324 325 switch v := value.(type) { 326 case *bgp.IPAddrPrefix: 327 nlri = &api.IPAddressPrefix{ 328 PrefixLen: uint32(v.Length), 329 Prefix: v.Prefix.String(), 330 } 331 case *bgp.IPv6AddrPrefix: 332 nlri = &api.IPAddressPrefix{ 333 PrefixLen: uint32(v.Length), 334 Prefix: v.Prefix.String(), 335 } 336 case *bgp.LabeledIPAddrPrefix: 337 nlri = &api.LabeledIPAddressPrefix{ 338 Labels: v.Labels.Labels, 339 PrefixLen: uint32(v.IPPrefixLen()), 340 Prefix: v.Prefix.String(), 341 } 342 case *bgp.LabeledIPv6AddrPrefix: 343 nlri = &api.LabeledIPAddressPrefix{ 344 Labels: v.Labels.Labels, 345 PrefixLen: uint32(v.IPPrefixLen()), 346 Prefix: v.Prefix.String(), 347 } 348 case *bgp.EncapNLRI: 349 nlri = &api.EncapsulationNLRI{ 350 Address: v.String(), 351 } 352 case *bgp.Encapv6NLRI: 353 nlri = &api.EncapsulationNLRI{ 354 Address: v.String(), 355 } 356 case *bgp.EVPNNLRI: 357 switch r := v.RouteTypeData.(type) { 358 case *bgp.EVPNEthernetAutoDiscoveryRoute: 359 nlri = &api.EVPNEthernetAutoDiscoveryRoute{ 360 Rd: MarshalRD(r.RD), 361 Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), 362 EthernetTag: r.ETag, 363 Label: r.Label, 364 } 365 case *bgp.EVPNMacIPAdvertisementRoute: 366 nlri = &api.EVPNMACIPAdvertisementRoute{ 367 Rd: MarshalRD(r.RD), 368 Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), 369 EthernetTag: r.ETag, 370 MacAddress: r.MacAddress.String(), 371 IpAddress: r.IPAddress.String(), 372 Labels: r.Labels, 373 } 374 case *bgp.EVPNMulticastEthernetTagRoute: 375 nlri = &api.EVPNInclusiveMulticastEthernetTagRoute{ 376 Rd: MarshalRD(r.RD), 377 EthernetTag: r.ETag, 378 IpAddress: r.IPAddress.String(), 379 } 380 case *bgp.EVPNEthernetSegmentRoute: 381 nlri = &api.EVPNEthernetSegmentRoute{ 382 Rd: MarshalRD(r.RD), 383 Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), 384 IpAddress: r.IPAddress.String(), 385 } 386 case *bgp.EVPNIPPrefixRoute: 387 nlri = &api.EVPNIPPrefixRoute{ 388 Rd: MarshalRD(r.RD), 389 Esi: NewEthernetSegmentIdentifierFromNative(&r.ESI), 390 EthernetTag: r.ETag, 391 IpPrefix: r.IPPrefix.String(), 392 IpPrefixLen: uint32(r.IPPrefixLength), 393 Label: r.Label, 394 GwAddress: r.GWIPAddress.String(), 395 } 396 } 397 case *bgp.LabeledVPNIPAddrPrefix: 398 nlri = &api.LabeledVPNIPAddressPrefix{ 399 Labels: v.Labels.Labels, 400 Rd: MarshalRD(v.RD), 401 PrefixLen: uint32(v.IPPrefixLen()), 402 Prefix: v.Prefix.String(), 403 } 404 case *bgp.LabeledVPNIPv6AddrPrefix: 405 nlri = &api.LabeledVPNIPAddressPrefix{ 406 Labels: v.Labels.Labels, 407 Rd: MarshalRD(v.RD), 408 PrefixLen: uint32(v.IPPrefixLen()), 409 Prefix: v.Prefix.String(), 410 } 411 case *bgp.RouteTargetMembershipNLRI: 412 nlri = &api.RouteTargetMembershipNLRI{ 413 As: v.AS, 414 Rt: MarshalRT(v.RouteTarget), 415 } 416 case *bgp.FlowSpecIPv4Unicast: 417 nlri = &api.FlowSpecNLRI{ 418 Rules: MarshalFlowSpecRules(v.Value), 419 } 420 case *bgp.FlowSpecIPv6Unicast: 421 nlri = &api.FlowSpecNLRI{ 422 Rules: MarshalFlowSpecRules(v.Value), 423 } 424 case *bgp.FlowSpecIPv4VPN: 425 nlri = &api.VPNFlowSpecNLRI{ 426 Rd: MarshalRD(v.RD()), 427 Rules: MarshalFlowSpecRules(v.Value), 428 } 429 case *bgp.FlowSpecIPv6VPN: 430 nlri = &api.VPNFlowSpecNLRI{ 431 Rd: MarshalRD(v.RD()), 432 Rules: MarshalFlowSpecRules(v.Value), 433 } 434 case *bgp.FlowSpecL2VPN: 435 nlri = &api.VPNFlowSpecNLRI{ 436 Rd: MarshalRD(v.RD()), 437 Rules: MarshalFlowSpecRules(v.Value), 438 } 439 } 440 441 an, _ := ptypes.MarshalAny(nlri) 442 return an 443 } 444 445 func MarshalNLRIs(values []bgp.AddrPrefixInterface) []*any.Any { 446 nlris := make([]*any.Any, 0, len(values)) 447 for _, value := range values { 448 nlris = append(nlris, MarshalNLRI(value)) 449 } 450 return nlris 451 } 452 453 func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, error) { 454 var nlri bgp.AddrPrefixInterface 455 456 var value ptypes.DynamicAny 457 if err := ptypes.UnmarshalAny(an, &value); err != nil { 458 return nil, fmt.Errorf("failed to unmarshal nlri: %s", err) 459 } 460 461 switch v := value.Message.(type) { 462 case *api.IPAddressPrefix: 463 switch rf { 464 case bgp.RF_IPv4_UC: 465 nlri = bgp.NewIPAddrPrefix(uint8(v.PrefixLen), v.Prefix) 466 case bgp.RF_IPv6_UC: 467 nlri = bgp.NewIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix) 468 } 469 case *api.LabeledIPAddressPrefix: 470 switch rf { 471 case bgp.RF_IPv4_MPLS: 472 nlri = bgp.NewLabeledIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) 473 case bgp.RF_IPv6_MPLS: 474 nlri = bgp.NewLabeledIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...)) 475 } 476 case *api.EncapsulationNLRI: 477 switch rf { 478 case bgp.RF_IPv4_ENCAP: 479 nlri = bgp.NewEncapNLRI(v.Address) 480 case bgp.RF_IPv6_ENCAP: 481 nlri = bgp.NewEncapv6NLRI(v.Address) 482 } 483 case *api.EVPNEthernetAutoDiscoveryRoute: 484 if rf == bgp.RF_EVPN { 485 rd, err := UnmarshalRD(v.Rd) 486 if err != nil { 487 return nil, err 488 } 489 esi, err := unmarshalESI(v.Esi) 490 if err != nil { 491 return nil, err 492 } 493 nlri = bgp.NewEVPNEthernetAutoDiscoveryRoute(rd, *esi, v.EthernetTag, v.Label) 494 } 495 case *api.EVPNMACIPAdvertisementRoute: 496 if rf == bgp.RF_EVPN { 497 rd, err := UnmarshalRD(v.Rd) 498 if err != nil { 499 return nil, err 500 } 501 esi, err := unmarshalESI(v.Esi) 502 if err != nil { 503 return nil, err 504 } 505 nlri = bgp.NewEVPNMacIPAdvertisementRoute(rd, *esi, v.EthernetTag, v.MacAddress, v.IpAddress, v.Labels) 506 } 507 case *api.EVPNInclusiveMulticastEthernetTagRoute: 508 if rf == bgp.RF_EVPN { 509 rd, err := UnmarshalRD(v.Rd) 510 if err != nil { 511 return nil, err 512 } 513 nlri = bgp.NewEVPNMulticastEthernetTagRoute(rd, v.EthernetTag, v.IpAddress) 514 } 515 case *api.EVPNEthernetSegmentRoute: 516 if rf == bgp.RF_EVPN { 517 rd, err := UnmarshalRD(v.Rd) 518 if err != nil { 519 return nil, err 520 } 521 esi, err := unmarshalESI(v.Esi) 522 if err != nil { 523 return nil, err 524 } 525 nlri = bgp.NewEVPNEthernetSegmentRoute(rd, *esi, v.IpAddress) 526 } 527 case *api.EVPNIPPrefixRoute: 528 if rf == bgp.RF_EVPN { 529 rd, err := UnmarshalRD(v.Rd) 530 if err != nil { 531 return nil, err 532 } 533 esi, err := unmarshalESI(v.Esi) 534 if err != nil { 535 return nil, err 536 } 537 nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label) 538 } 539 case *api.LabeledVPNIPAddressPrefix: 540 rd, err := UnmarshalRD(v.Rd) 541 if err != nil { 542 return nil, err 543 } 544 switch rf { 545 case bgp.RF_IPv4_VPN: 546 nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) 547 case bgp.RF_IPv6_VPN: 548 nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(v.PrefixLen), v.Prefix, *bgp.NewMPLSLabelStack(v.Labels...), rd) 549 } 550 case *api.RouteTargetMembershipNLRI: 551 rt, err := UnmarshalRT(v.Rt) 552 if err != nil { 553 return nil, err 554 } 555 nlri = bgp.NewRouteTargetMembershipNLRI(v.As, rt) 556 case *api.FlowSpecNLRI: 557 rules, err := UnmarshalFlowSpecRules(v.Rules) 558 if err != nil { 559 return nil, err 560 } 561 switch rf { 562 case bgp.RF_FS_IPv4_UC: 563 nlri = bgp.NewFlowSpecIPv4Unicast(rules) 564 case bgp.RF_FS_IPv6_UC: 565 nlri = bgp.NewFlowSpecIPv6Unicast(rules) 566 } 567 case *api.VPNFlowSpecNLRI: 568 rd, err := UnmarshalRD(v.Rd) 569 if err != nil { 570 return nil, err 571 } 572 rules, err := UnmarshalFlowSpecRules(v.Rules) 573 if err != nil { 574 return nil, err 575 } 576 switch rf { 577 case bgp.RF_FS_IPv4_VPN: 578 nlri = bgp.NewFlowSpecIPv4VPN(rd, rules) 579 case bgp.RF_FS_IPv6_VPN: 580 nlri = bgp.NewFlowSpecIPv6VPN(rd, rules) 581 case bgp.RF_FS_L2_VPN: 582 nlri = bgp.NewFlowSpecL2VPN(rd, rules) 583 } 584 } 585 586 if nlri == nil { 587 return nil, fmt.Errorf("invalid nlri for %s family: %s", rf.String(), value.Message) 588 } 589 590 return nlri, nil 591 } 592 593 func UnmarshalNLRIs(rf bgp.RouteFamily, values []*any.Any) ([]bgp.AddrPrefixInterface, error) { 594 nlris := make([]bgp.AddrPrefixInterface, 0, len(values)) 595 for _, an := range values { 596 nlri, err := UnmarshalNLRI(rf, an) 597 if err != nil { 598 return nil, err 599 } 600 nlris = append(nlris, nlri) 601 } 602 return nlris, nil 603 } 604 605 func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *api.MpReachNLRIAttribute { 606 var nexthops []string 607 if a.SAFI == bgp.SAFI_FLOW_SPEC_UNICAST || a.SAFI == bgp.SAFI_FLOW_SPEC_VPN { 608 nexthops = nil 609 } else { 610 nexthops = []string{a.Nexthop.String()} 611 if a.LinkLocalNexthop != nil { 612 nexthops = append(nexthops, a.LinkLocalNexthop.String()) 613 } 614 } 615 return &api.MpReachNLRIAttribute{ 616 Family: ToApiFamily(a.AFI, a.SAFI), 617 NextHops: nexthops, 618 Nlris: MarshalNLRIs(a.Value), 619 } 620 } 621 622 func NewMpUnreachNLRIAttributeFromNative(a *bgp.PathAttributeMpUnreachNLRI) *api.MpUnreachNLRIAttribute { 623 return &api.MpUnreachNLRIAttribute{ 624 Family: ToApiFamily(a.AFI, a.SAFI), 625 Nlris: MarshalNLRIs(a.Value), 626 } 627 } 628 629 func MarshalRT(rt bgp.ExtendedCommunityInterface) *any.Any { 630 var r proto.Message 631 switch v := rt.(type) { 632 case *bgp.TwoOctetAsSpecificExtended: 633 r = &api.TwoOctetAsSpecificExtended{ 634 IsTransitive: true, 635 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 636 As: uint32(v.AS), 637 LocalAdmin: uint32(v.LocalAdmin), 638 } 639 case *bgp.IPv4AddressSpecificExtended: 640 r = &api.IPv4AddressSpecificExtended{ 641 IsTransitive: true, 642 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 643 Address: v.IPv4.String(), 644 LocalAdmin: uint32(v.LocalAdmin), 645 } 646 case *bgp.FourOctetAsSpecificExtended: 647 r = &api.FourOctetAsSpecificExtended{ 648 IsTransitive: true, 649 SubType: uint32(bgp.EC_SUBTYPE_ROUTE_TARGET), 650 As: uint32(v.AS), 651 LocalAdmin: uint32(v.LocalAdmin), 652 } 653 default: 654 log.WithFields(log.Fields{ 655 "Topic": "protobuf", 656 "RT": rt, 657 }).Warn("invalid rt type to marshal") 658 return nil 659 } 660 a, _ := ptypes.MarshalAny(r) 661 return a 662 } 663 664 func MarshalRTs(values []bgp.ExtendedCommunityInterface) []*any.Any { 665 rts := make([]*any.Any, 0, len(values)) 666 for _, rt := range values { 667 rts = append(rts, MarshalRT(rt)) 668 } 669 return rts 670 } 671 672 func UnmarshalRT(a *any.Any) (bgp.ExtendedCommunityInterface, error) { 673 var value ptypes.DynamicAny 674 if err := ptypes.UnmarshalAny(a, &value); err != nil { 675 return nil, fmt.Errorf("failed to unmarshal route target: %s", err) 676 } 677 switch v := value.Message.(type) { 678 case *api.TwoOctetAsSpecificExtended: 679 return bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive), nil 680 case *api.IPv4AddressSpecificExtended: 681 rt := bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 682 if rt == nil { 683 return nil, fmt.Errorf("invalid address for ipv4 address specific route target: %s", v.Address) 684 } 685 return rt, nil 686 case *api.FourOctetAsSpecificExtended: 687 return bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive), nil 688 } 689 return nil, fmt.Errorf("invalid route target type: %s", a.TypeUrl) 690 } 691 692 func UnmarshalRTs(values []*any.Any) ([]bgp.ExtendedCommunityInterface, error) { 693 rts := make([]bgp.ExtendedCommunityInterface, 0, len(values)) 694 for _, an := range values { 695 rt, err := UnmarshalRT(an) 696 if err != nil { 697 return nil, err 698 } 699 rts = append(rts, rt) 700 } 701 return rts, nil 702 } 703 704 func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommunities) *api.ExtendedCommunitiesAttribute { 705 communities := make([]*any.Any, 0, len(a.Value)) 706 for _, value := range a.Value { 707 var community proto.Message 708 switch v := value.(type) { 709 case *bgp.TwoOctetAsSpecificExtended: 710 community = &api.TwoOctetAsSpecificExtended{ 711 IsTransitive: v.IsTransitive, 712 SubType: uint32(v.SubType), 713 As: uint32(v.AS), 714 LocalAdmin: uint32(v.LocalAdmin), 715 } 716 case *bgp.IPv4AddressSpecificExtended: 717 community = &api.IPv4AddressSpecificExtended{ 718 IsTransitive: v.IsTransitive, 719 SubType: uint32(v.SubType), 720 Address: v.IPv4.String(), 721 LocalAdmin: uint32(v.LocalAdmin), 722 } 723 case *bgp.FourOctetAsSpecificExtended: 724 community = &api.FourOctetAsSpecificExtended{ 725 IsTransitive: v.IsTransitive, 726 SubType: uint32(v.SubType), 727 As: uint32(v.AS), 728 LocalAdmin: uint32(v.LocalAdmin), 729 } 730 case *bgp.ValidationExtended: 731 community = &api.ValidationExtended{ 732 State: uint32(v.State), 733 } 734 case *bgp.ColorExtended: 735 community = &api.ColorExtended{ 736 Color: v.Color, 737 } 738 case *bgp.EncapExtended: 739 community = &api.EncapExtended{ 740 TunnelType: uint32(v.TunnelType), 741 } 742 case *bgp.DefaultGatewayExtended: 743 community = &api.DefaultGatewayExtended{} 744 case *bgp.OpaqueExtended: 745 community = &api.OpaqueExtended{ 746 IsTransitive: v.IsTransitive, 747 Value: v.Value, 748 } 749 case *bgp.ESILabelExtended: 750 community = &api.ESILabelExtended{ 751 IsSingleActive: v.IsSingleActive, 752 Label: v.Label, 753 } 754 case *bgp.ESImportRouteTarget: 755 community = &api.ESImportRouteTarget{ 756 EsImport: v.ESImport.String(), 757 } 758 case *bgp.MacMobilityExtended: 759 community = &api.MacMobilityExtended{ 760 IsSticky: v.IsSticky, 761 SequenceNum: v.Sequence, 762 } 763 case *bgp.RouterMacExtended: 764 community = &api.RouterMacExtended{ 765 Mac: v.Mac.String(), 766 } 767 case *bgp.TrafficRateExtended: 768 community = &api.TrafficRateExtended{ 769 As: uint32(v.AS), 770 Rate: v.Rate, 771 } 772 case *bgp.TrafficActionExtended: 773 community = &api.TrafficActionExtended{ 774 Terminal: v.Terminal, 775 Sample: v.Sample, 776 } 777 case *bgp.RedirectTwoOctetAsSpecificExtended: 778 community = &api.RedirectTwoOctetAsSpecificExtended{ 779 As: uint32(v.AS), 780 LocalAdmin: v.LocalAdmin, 781 } 782 case *bgp.RedirectIPv4AddressSpecificExtended: 783 community = &api.RedirectIPv4AddressSpecificExtended{ 784 Address: v.IPv4.String(), 785 LocalAdmin: uint32(v.LocalAdmin), 786 } 787 case *bgp.RedirectFourOctetAsSpecificExtended: 788 community = &api.RedirectFourOctetAsSpecificExtended{ 789 As: v.AS, 790 LocalAdmin: uint32(v.LocalAdmin), 791 } 792 case *bgp.TrafficRemarkExtended: 793 community = &api.TrafficRemarkExtended{ 794 Dscp: uint32(v.DSCP), 795 } 796 case *bgp.UnknownExtended: 797 community = &api.UnknownExtended{ 798 Type: uint32(v.Type), 799 Value: v.Value, 800 } 801 default: 802 log.WithFields(log.Fields{ 803 "Topic": "protobuf", 804 "Community": value, 805 }).Warn("unsupported extended community") 806 return nil 807 } 808 an, _ := ptypes.MarshalAny(community) 809 communities = append(communities, an) 810 } 811 return &api.ExtendedCommunitiesAttribute{ 812 Communities: communities, 813 } 814 } 815 816 func unmarshalExComm(a *api.ExtendedCommunitiesAttribute) (*bgp.PathAttributeExtendedCommunities, error) { 817 communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) 818 for _, an := range a.Communities { 819 var community bgp.ExtendedCommunityInterface 820 var value ptypes.DynamicAny 821 if err := ptypes.UnmarshalAny(an, &value); err != nil { 822 return nil, fmt.Errorf("failed to unmarshal extended community: %s", err) 823 } 824 switch v := value.Message.(type) { 825 case *api.TwoOctetAsSpecificExtended: 826 community = bgp.NewTwoOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), uint16(v.As), v.LocalAdmin, v.IsTransitive) 827 case *api.IPv4AddressSpecificExtended: 828 community = bgp.NewIPv4AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 829 case *api.FourOctetAsSpecificExtended: 830 community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive) 831 case *api.ValidationExtended: 832 community = bgp.NewValidationExtended(bgp.ValidationState(v.State)) 833 case *api.ColorExtended: 834 community = bgp.NewColorExtended(v.Color) 835 case *api.EncapExtended: 836 community = bgp.NewEncapExtended(bgp.TunnelType(v.TunnelType)) 837 case *api.DefaultGatewayExtended: 838 community = bgp.NewDefaultGatewayExtended() 839 case *api.OpaqueExtended: 840 community = bgp.NewOpaqueExtended(v.IsTransitive, v.Value) 841 case *api.ESILabelExtended: 842 community = bgp.NewESILabelExtended(v.Label, v.IsSingleActive) 843 case *api.ESImportRouteTarget: 844 community = bgp.NewESImportRouteTarget(v.EsImport) 845 case *api.MacMobilityExtended: 846 community = bgp.NewMacMobilityExtended(v.SequenceNum, v.IsSticky) 847 case *api.RouterMacExtended: 848 community = bgp.NewRoutersMacExtended(v.Mac) 849 case *api.TrafficRateExtended: 850 community = bgp.NewTrafficRateExtended(uint16(v.As), v.Rate) 851 case *api.TrafficActionExtended: 852 community = bgp.NewTrafficActionExtended(v.Terminal, v.Sample) 853 case *api.RedirectTwoOctetAsSpecificExtended: 854 community = bgp.NewRedirectTwoOctetAsSpecificExtended(uint16(v.As), v.LocalAdmin) 855 case *api.RedirectIPv4AddressSpecificExtended: 856 community = bgp.NewRedirectIPv4AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) 857 case *api.RedirectFourOctetAsSpecificExtended: 858 community = bgp.NewRedirectFourOctetAsSpecificExtended(v.As, uint16(v.LocalAdmin)) 859 case *api.TrafficRemarkExtended: 860 community = bgp.NewTrafficRemarkExtended(uint8(v.Dscp)) 861 case *api.UnknownExtended: 862 community = bgp.NewUnknownExtended(bgp.ExtendedCommunityAttrType(v.Type), v.Value) 863 } 864 if community == nil { 865 return nil, fmt.Errorf("invalid extended community: %v", value.Message) 866 } 867 communities = append(communities, community) 868 } 869 return bgp.NewPathAttributeExtendedCommunities(communities), nil 870 } 871 872 func NewAs4PathAttributeFromNative(a *bgp.PathAttributeAs4Path) *api.As4PathAttribute { 873 segments := make([]*api.AsSegment, 0, len(a.Value)) 874 for _, param := range a.Value { 875 segments = append(segments, &api.AsSegment{ 876 Type: uint32(param.Type), 877 Numbers: param.AS, 878 }) 879 } 880 return &api.As4PathAttribute{ 881 Segments: segments, 882 } 883 } 884 885 func NewAs4AggregatorAttributeFromNative(a *bgp.PathAttributeAs4Aggregator) *api.As4AggregatorAttribute { 886 return &api.As4AggregatorAttribute{ 887 As: a.Value.AS, 888 Address: a.Value.Address.String(), 889 } 890 } 891 892 func NewPmsiTunnelAttributeFromNative(a *bgp.PathAttributePmsiTunnel) *api.PmsiTunnelAttribute { 893 var flags uint32 894 if a.IsLeafInfoRequired { 895 flags |= 0x01 896 } 897 id, _ := a.TunnelID.Serialize() 898 return &api.PmsiTunnelAttribute{ 899 Flags: flags, 900 Type: uint32(a.TunnelType), 901 Label: a.Label, 902 Id: id, 903 } 904 } 905 906 func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.TunnelEncapAttribute { 907 tlvs := make([]*api.TunnelEncapTLV, 0, len(a.Value)) 908 for _, v := range a.Value { 909 subTlvs := make([]*any.Any, 0, len(v.Value)) 910 for _, s := range v.Value { 911 var subTlv proto.Message 912 switch sv := s.(type) { 913 case *bgp.TunnelEncapSubTLVEncapsulation: 914 subTlv = &api.TunnelEncapSubTLVEncapsulation{ 915 Key: sv.Key, 916 Cookie: sv.Cookie, 917 } 918 case *bgp.TunnelEncapSubTLVProtocol: 919 subTlv = &api.TunnelEncapSubTLVProtocol{ 920 Protocol: uint32(sv.Protocol), 921 } 922 case *bgp.TunnelEncapSubTLVColor: 923 subTlv = &api.TunnelEncapSubTLVColor{ 924 Color: sv.Color, 925 } 926 case *bgp.TunnelEncapSubTLVUnknown: 927 subTlv = &api.TunnelEncapSubTLVUnknown{ 928 Type: uint32(sv.Type), 929 Value: sv.Value, 930 } 931 } 932 an, _ := ptypes.MarshalAny(subTlv) 933 subTlvs = append(subTlvs, an) 934 } 935 tlvs = append(tlvs, &api.TunnelEncapTLV{ 936 Type: uint32(v.Type), 937 Tlvs: subTlvs, 938 }) 939 } 940 return &api.TunnelEncapAttribute{ 941 Tlvs: tlvs, 942 } 943 } 944 945 func NewIP6ExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeIP6ExtendedCommunities) *api.IP6ExtendedCommunitiesAttribute { 946 communities := make([]*any.Any, 0, len(a.Value)) 947 for _, value := range a.Value { 948 var community proto.Message 949 switch v := value.(type) { 950 case *bgp.IPv6AddressSpecificExtended: 951 community = &api.IPv6AddressSpecificExtended{ 952 IsTransitive: v.IsTransitive, 953 SubType: uint32(v.SubType), 954 Address: v.IPv6.String(), 955 LocalAdmin: uint32(v.LocalAdmin), 956 } 957 case *bgp.RedirectIPv6AddressSpecificExtended: 958 community = &api.RedirectIPv6AddressSpecificExtended{ 959 Address: v.IPv6.String(), 960 LocalAdmin: uint32(v.LocalAdmin), 961 } 962 default: 963 log.WithFields(log.Fields{ 964 "Topic": "protobuf", 965 "Attribute": value, 966 }).Warn("invalid ipv6 extended community") 967 return nil 968 } 969 an, _ := ptypes.MarshalAny(community) 970 communities = append(communities, an) 971 } 972 return &api.IP6ExtendedCommunitiesAttribute{ 973 Communities: communities, 974 } 975 } 976 977 func NewAigpAttributeFromNative(a *bgp.PathAttributeAigp) *api.AigpAttribute { 978 tlvs := make([]*any.Any, 0, len(a.Values)) 979 for _, value := range a.Values { 980 var tlv proto.Message 981 switch v := value.(type) { 982 case *bgp.AigpTLVIgpMetric: 983 tlv = &api.AigpTLVIGPMetric{ 984 Metric: v.Metric, 985 } 986 case *bgp.AigpTLVDefault: 987 tlv = &api.AigpTLVUnknown{ 988 Type: uint32(v.Type()), 989 Value: v.Value, 990 } 991 } 992 an, _ := ptypes.MarshalAny(tlv) 993 tlvs = append(tlvs, an) 994 } 995 return &api.AigpAttribute{ 996 Tlvs: tlvs, 997 } 998 } 999 1000 func NewLargeCommunitiesAttributeFromNative(a *bgp.PathAttributeLargeCommunities) *api.LargeCommunitiesAttribute { 1001 communities := make([]*api.LargeCommunity, 0, len(a.Values)) 1002 for _, v := range a.Values { 1003 communities = append(communities, &api.LargeCommunity{ 1004 GlobalAdmin: v.ASN, 1005 LocalData1: v.LocalData1, 1006 LocalData2: v.LocalData2, 1007 }) 1008 } 1009 return &api.LargeCommunitiesAttribute{ 1010 Communities: communities, 1011 } 1012 } 1013 1014 func NewUnknownAttributeFromNative(a *bgp.PathAttributeUnknown) *api.UnknownAttribute { 1015 return &api.UnknownAttribute{ 1016 Flags: uint32(a.Flags), 1017 Type: uint32(a.Type), 1018 Value: a.Value, 1019 } 1020 } 1021 1022 func MarshalPathAttributes(attrList []bgp.PathAttributeInterface) []*any.Any { 1023 anyList := make([]*any.Any, 0, len(attrList)) 1024 for _, attr := range attrList { 1025 switch a := attr.(type) { 1026 case *bgp.PathAttributeOrigin: 1027 n, _ := ptypes.MarshalAny(NewOriginAttributeFromNative(a)) 1028 anyList = append(anyList, n) 1029 case *bgp.PathAttributeAsPath: 1030 n, _ := ptypes.MarshalAny(NewAsPathAttributeFromNative(a)) 1031 anyList = append(anyList, n) 1032 case *bgp.PathAttributeNextHop: 1033 n, _ := ptypes.MarshalAny(NewNextHopAttributeFromNative(a)) 1034 anyList = append(anyList, n) 1035 case *bgp.PathAttributeMultiExitDisc: 1036 n, _ := ptypes.MarshalAny(NewMultiExitDiscAttributeFromNative(a)) 1037 anyList = append(anyList, n) 1038 case *bgp.PathAttributeLocalPref: 1039 n, _ := ptypes.MarshalAny(NewLocalPrefAttributeFromNative(a)) 1040 anyList = append(anyList, n) 1041 case *bgp.PathAttributeAtomicAggregate: 1042 n, _ := ptypes.MarshalAny(NewAtomicAggregateAttributeFromNative(a)) 1043 anyList = append(anyList, n) 1044 case *bgp.PathAttributeAggregator: 1045 n, _ := ptypes.MarshalAny(NewAggregatorAttributeFromNative(a)) 1046 anyList = append(anyList, n) 1047 case *bgp.PathAttributeCommunities: 1048 n, _ := ptypes.MarshalAny(NewCommunitiesAttributeFromNative(a)) 1049 anyList = append(anyList, n) 1050 case *bgp.PathAttributeOriginatorId: 1051 n, _ := ptypes.MarshalAny(NewOriginatorIdAttributeFromNative(a)) 1052 anyList = append(anyList, n) 1053 case *bgp.PathAttributeClusterList: 1054 n, _ := ptypes.MarshalAny(NewClusterListAttributeFromNative(a)) 1055 anyList = append(anyList, n) 1056 case *bgp.PathAttributeMpReachNLRI: 1057 n, _ := ptypes.MarshalAny(NewMpReachNLRIAttributeFromNative(a)) 1058 anyList = append(anyList, n) 1059 case *bgp.PathAttributeMpUnreachNLRI: 1060 n, _ := ptypes.MarshalAny(NewMpUnreachNLRIAttributeFromNative(a)) 1061 anyList = append(anyList, n) 1062 case *bgp.PathAttributeExtendedCommunities: 1063 n, _ := ptypes.MarshalAny(NewExtendedCommunitiesAttributeFromNative(a)) 1064 anyList = append(anyList, n) 1065 case *bgp.PathAttributeAs4Path: 1066 n, _ := ptypes.MarshalAny(NewAs4PathAttributeFromNative(a)) 1067 anyList = append(anyList, n) 1068 case *bgp.PathAttributeAs4Aggregator: 1069 n, _ := ptypes.MarshalAny(NewAs4AggregatorAttributeFromNative(a)) 1070 anyList = append(anyList, n) 1071 case *bgp.PathAttributePmsiTunnel: 1072 n, _ := ptypes.MarshalAny(NewPmsiTunnelAttributeFromNative(a)) 1073 anyList = append(anyList, n) 1074 case *bgp.PathAttributeTunnelEncap: 1075 n, _ := ptypes.MarshalAny(NewTunnelEncapAttributeFromNative(a)) 1076 anyList = append(anyList, n) 1077 case *bgp.PathAttributeIP6ExtendedCommunities: 1078 n, _ := ptypes.MarshalAny(NewIP6ExtendedCommunitiesAttributeFromNative(a)) 1079 anyList = append(anyList, n) 1080 case *bgp.PathAttributeAigp: 1081 n, _ := ptypes.MarshalAny(NewAigpAttributeFromNative(a)) 1082 anyList = append(anyList, n) 1083 case *bgp.PathAttributeLargeCommunities: 1084 n, _ := ptypes.MarshalAny(NewLargeCommunitiesAttributeFromNative(a)) 1085 anyList = append(anyList, n) 1086 case *bgp.PathAttributeUnknown: 1087 n, _ := ptypes.MarshalAny(NewUnknownAttributeFromNative(a)) 1088 anyList = append(anyList, n) 1089 } 1090 } 1091 return anyList 1092 } 1093 1094 func UnmarshalPathAttributes(values []*any.Any) ([]bgp.PathAttributeInterface, error) { 1095 attrList := make([]bgp.PathAttributeInterface, 0, len(values)) 1096 typeMap := make(map[bgp.BGPAttrType]struct{}) 1097 for _, an := range values { 1098 attr, err := unmarshalAttribute(an) 1099 if err != nil { 1100 return nil, err 1101 } 1102 if _, ok := typeMap[attr.GetType()]; ok { 1103 return nil, fmt.Errorf("duplicated path attribute type: %d", attr.GetType()) 1104 } 1105 typeMap[attr.GetType()] = struct{}{} 1106 attrList = append(attrList, attr) 1107 } 1108 return attrList, nil 1109 } 1110 1111 func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) { 1112 var value ptypes.DynamicAny 1113 if err := ptypes.UnmarshalAny(an, &value); err != nil { 1114 return nil, fmt.Errorf("failed to unmarshal route distinguisher: %s", err) 1115 } 1116 switch a := value.Message.(type) { 1117 case *api.OriginAttribute: 1118 return bgp.NewPathAttributeOrigin(uint8(a.Origin)), nil 1119 case *api.AsPathAttribute: 1120 params := make([]bgp.AsPathParamInterface, 0, len(a.Segments)) 1121 for _, segment := range a.Segments { 1122 params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) 1123 } 1124 return bgp.NewPathAttributeAsPath(params), nil 1125 case *api.NextHopAttribute: 1126 nexthop := net.ParseIP(a.NextHop).To4() 1127 if nexthop == nil { 1128 return nil, fmt.Errorf("invalid nexthop address: %s", a.NextHop) 1129 } 1130 return bgp.NewPathAttributeNextHop(a.NextHop), nil 1131 case *api.MultiExitDiscAttribute: 1132 return bgp.NewPathAttributeMultiExitDisc(a.Med), nil 1133 case *api.LocalPrefAttribute: 1134 return bgp.NewPathAttributeLocalPref(a.LocalPref), nil 1135 case *api.AtomicAggregateAttribute: 1136 return bgp.NewPathAttributeAtomicAggregate(), nil 1137 case *api.AggregatorAttribute: 1138 if net.ParseIP(a.Address).To4() == nil { 1139 return nil, fmt.Errorf("invalid aggregator address: %s", a.Address) 1140 } 1141 return bgp.NewPathAttributeAggregator(a.As, a.Address), nil 1142 case *api.CommunitiesAttribute: 1143 return bgp.NewPathAttributeCommunities(a.Communities), nil 1144 case *api.OriginatorIdAttribute: 1145 if net.ParseIP(a.Id).To4() == nil { 1146 return nil, fmt.Errorf("invalid originator id: %s", a.Id) 1147 } 1148 return bgp.NewPathAttributeOriginatorId(a.Id), nil 1149 case *api.ClusterListAttribute: 1150 for _, id := range a.Ids { 1151 if net.ParseIP(id).To4() == nil { 1152 return nil, fmt.Errorf("invalid cluster list: %s", a.Ids) 1153 } 1154 } 1155 return bgp.NewPathAttributeClusterList(a.Ids), nil 1156 case *api.MpReachNLRIAttribute: 1157 rf := ToRouteFamily(a.Family) 1158 nlris, err := UnmarshalNLRIs(rf, a.Nlris) 1159 if err != nil { 1160 return nil, err 1161 } 1162 afi, safi := bgp.RouteFamilyToAfiSafi(rf) 1163 nexthop := "0.0.0.0" 1164 var linkLocalNexthop net.IP 1165 if afi == bgp.AFI_IP6 { 1166 nexthop = "::" 1167 if len(a.NextHops) > 1 { 1168 linkLocalNexthop = net.ParseIP(a.NextHops[1]).To16() 1169 if linkLocalNexthop == nil { 1170 return nil, fmt.Errorf("invalid nexthop: %s", a.NextHops[1]) 1171 } 1172 } 1173 } 1174 if safi == bgp.SAFI_FLOW_SPEC_UNICAST || safi == bgp.SAFI_FLOW_SPEC_VPN { 1175 nexthop = "" 1176 } else if len(a.NextHops) > 0 { 1177 nexthop = a.NextHops[0] 1178 if net.ParseIP(nexthop) == nil { 1179 return nil, fmt.Errorf("invalid nexthop: %s", nexthop) 1180 } 1181 } 1182 attr := bgp.NewPathAttributeMpReachNLRI(nexthop, nlris) 1183 attr.LinkLocalNexthop = linkLocalNexthop 1184 return attr, nil 1185 case *api.MpUnreachNLRIAttribute: 1186 rf := ToRouteFamily(a.Family) 1187 nlris, err := UnmarshalNLRIs(rf, a.Nlris) 1188 if err != nil { 1189 return nil, err 1190 } 1191 return bgp.NewPathAttributeMpUnreachNLRI(nlris), nil 1192 case *api.ExtendedCommunitiesAttribute: 1193 return unmarshalExComm(a) 1194 case *api.As4PathAttribute: 1195 params := make([]*bgp.As4PathParam, 0, len(a.Segments)) 1196 for _, segment := range a.Segments { 1197 params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) 1198 } 1199 return bgp.NewPathAttributeAs4Path(params), nil 1200 case *api.As4AggregatorAttribute: 1201 if net.ParseIP(a.Address).To4() == nil { 1202 return nil, fmt.Errorf("invalid as4 aggregator address: %s", a.Address) 1203 } 1204 return bgp.NewPathAttributeAs4Aggregator(a.As, a.Address), nil 1205 case *api.PmsiTunnelAttribute: 1206 typ := bgp.PmsiTunnelType(a.Type) 1207 var isLeafInfoRequired bool 1208 if a.Flags&0x01 > 0 { 1209 isLeafInfoRequired = true 1210 } 1211 var id bgp.PmsiTunnelIDInterface 1212 switch typ { 1213 case bgp.PMSI_TUNNEL_TYPE_INGRESS_REPL: 1214 ip := net.IP(a.Id) 1215 if ip.To4() == nil && ip.To16() == nil { 1216 return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", a.Id) 1217 } 1218 id = bgp.NewIngressReplTunnelID(ip.String()) 1219 default: 1220 id = bgp.NewDefaultPmsiTunnelID(a.Id) 1221 } 1222 return bgp.NewPathAttributePmsiTunnel(typ, isLeafInfoRequired, a.Label, id), nil 1223 case *api.TunnelEncapAttribute: 1224 tlvs := make([]*bgp.TunnelEncapTLV, 0, len(a.Tlvs)) 1225 for _, tlv := range a.Tlvs { 1226 subTlvs := make([]bgp.TunnelEncapSubTLVInterface, 0, len(tlv.Tlvs)) 1227 for _, an := range tlv.Tlvs { 1228 var subTlv bgp.TunnelEncapSubTLVInterface 1229 var subValue ptypes.DynamicAny 1230 if err := ptypes.UnmarshalAny(an, &subValue); err != nil { 1231 return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err) 1232 } 1233 switch sv := subValue.Message.(type) { 1234 case *api.TunnelEncapSubTLVEncapsulation: 1235 subTlv = bgp.NewTunnelEncapSubTLVEncapsulation(sv.Key, sv.Cookie) 1236 case *api.TunnelEncapSubTLVProtocol: 1237 subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol)) 1238 case *api.TunnelEncapSubTLVColor: 1239 subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color) 1240 case *api.TunnelEncapSubTLVUnknown: 1241 subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value) 1242 default: 1243 return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message) 1244 } 1245 subTlvs = append(subTlvs, subTlv) 1246 } 1247 tlvs = append(tlvs, bgp.NewTunnelEncapTLV(bgp.TunnelType(tlv.Type), subTlvs)) 1248 } 1249 return bgp.NewPathAttributeTunnelEncap(tlvs), nil 1250 case *api.IP6ExtendedCommunitiesAttribute: 1251 communities := make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities)) 1252 for _, an := range a.Communities { 1253 var community bgp.ExtendedCommunityInterface 1254 var value ptypes.DynamicAny 1255 if err := ptypes.UnmarshalAny(an, &value); err != nil { 1256 return nil, fmt.Errorf("failed to unmarshal ipv6 extended community: %s", err) 1257 } 1258 switch v := value.Message.(type) { 1259 case *api.IPv6AddressSpecificExtended: 1260 community = bgp.NewIPv6AddressSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.Address, uint16(v.LocalAdmin), v.IsTransitive) 1261 case *api.RedirectIPv6AddressSpecificExtended: 1262 community = bgp.NewRedirectIPv6AddressSpecificExtended(v.Address, uint16(v.LocalAdmin)) 1263 } 1264 if community == nil { 1265 return nil, fmt.Errorf("invalid ipv6 extended community: %v", value.Message) 1266 } 1267 communities = append(communities, community) 1268 } 1269 return bgp.NewPathAttributeIP6ExtendedCommunities(communities), nil 1270 1271 case *api.AigpAttribute: 1272 tlvs := make([]bgp.AigpTLVInterface, 0, len(a.Tlvs)) 1273 for _, an := range a.Tlvs { 1274 var tlv bgp.AigpTLVInterface 1275 var value ptypes.DynamicAny 1276 if err := ptypes.UnmarshalAny(an, &value); err != nil { 1277 return nil, fmt.Errorf("failed to unmarshal aigp attribute tlv: %s", err) 1278 } 1279 switch v := value.Message.(type) { 1280 case *api.AigpTLVIGPMetric: 1281 tlv = bgp.NewAigpTLVIgpMetric(v.Metric) 1282 case *api.AigpTLVUnknown: 1283 tlv = bgp.NewAigpTLVDefault(bgp.AigpTLVType(v.Type), v.Value) 1284 } 1285 if tlv == nil { 1286 return nil, fmt.Errorf("invalid aigp attribute tlv: %v", value.Message) 1287 } 1288 tlvs = append(tlvs, tlv) 1289 } 1290 return bgp.NewPathAttributeAigp(tlvs), nil 1291 1292 case *api.LargeCommunitiesAttribute: 1293 communities := make([]*bgp.LargeCommunity, 0, len(a.Communities)) 1294 for _, c := range a.Communities { 1295 communities = append(communities, bgp.NewLargeCommunity(c.GlobalAdmin, c.LocalData1, c.LocalData2)) 1296 } 1297 return bgp.NewPathAttributeLargeCommunities(communities), nil 1298 1299 case *api.UnknownAttribute: 1300 return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil 1301 } 1302 return nil, errors.New("unknown path attribute") 1303 }