(resource api.TableType, path *api.Path, isWithdraw bool)
| 521 | } |
| 522 | |
| 523 | func api2Path(resource api.TableType, path *api.Path, isWithdraw bool) (*table.Path, error) { |
| 524 | var pi *table.PeerInfo |
| 525 | var nlri bgp.NLRI |
| 526 | var nexthop netip.Addr |
| 527 | |
| 528 | if path.SourceAsn != 0 { |
| 529 | id, err := netip.ParseAddr(path.SourceId) |
| 530 | if err != nil { |
| 531 | return nil, fmt.Errorf("invalid source ID: %w", err) |
| 532 | } |
| 533 | pi = &table.PeerInfo{ |
| 534 | AS: path.SourceAsn, |
| 535 | ID: id, |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | nlri, err := apiutil.GetNativeNlri(path) |
| 540 | if err != nil { |
| 541 | return nil, err |
| 542 | } |
| 543 | |
| 544 | attrList, err := apiutil.GetNativePathAttributes(path) |
| 545 | if err != nil { |
| 546 | return nil, err |
| 547 | } |
| 548 | |
| 549 | // TODO (sbezverk) At this poinnt nlri and path attributes are converted to native mode |
| 550 | // need to check if update with SR Policy nlri comes with mandatory route distinguisher |
| 551 | // extended community or NO_ADVERTISE community, with Tunnel Encapsulation Attribute 23 |
| 552 | // and tunnel type 15. If it is not the case ignore update and log an error. |
| 553 | |
| 554 | pattrs := make([]bgp.PathAttributeInterface, 0) |
| 555 | seen := make(map[bgp.BGPAttrType]struct{}) |
| 556 | for _, attr := range attrList { |
| 557 | attrType := attr.GetType() |
| 558 | if _, ok := seen[attrType]; !ok { |
| 559 | seen[attrType] = struct{}{} |
| 560 | } else { |
| 561 | return nil, fmt.Errorf("duplicated path attribute type: %d", attrType) |
| 562 | } |
| 563 | |
| 564 | switch a := attr.(type) { |
| 565 | case *bgp.PathAttributeNextHop: |
| 566 | nexthop = a.Value |
| 567 | case *bgp.PathAttributeMpReachNLRI: |
| 568 | if len(a.Value) == 0 { |
| 569 | return nil, fmt.Errorf("invalid mp reach attribute") |
| 570 | } |
| 571 | nexthop = a.Nexthop |
| 572 | default: |
| 573 | pattrs = append(pattrs, attr) |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | if !path.IsWithdraw && !nexthop.IsValid() { |
| 578 | return nil, fmt.Errorf("nexthop not found") |
| 579 | } |
| 580 | rf := bgp.NewFamily(uint16(path.Family.Afi), uint8(path.Family.Safi)) |
no test coverage detected
searching dependent graphs…