(attr *api.Attribute)
| 27 | ) |
| 28 | |
| 29 | func UnmarshalAttribute(attr *api.Attribute) (bgp.PathAttributeInterface, error) { |
| 30 | switch a := attr.GetAttr().(type) { |
| 31 | case *api.Attribute_Origin: |
| 32 | return bgp.NewPathAttributeOrigin(uint8(a.Origin.Origin)), nil |
| 33 | case *api.Attribute_AsPath: |
| 34 | params := make([]bgp.AsPathParamInterface, 0, len(a.AsPath.Segments)) |
| 35 | for _, segment := range a.AsPath.Segments { |
| 36 | params = append(params, bgp.NewAs4PathParam(uint8(segment.Type), segment.Numbers)) |
| 37 | } |
| 38 | return bgp.NewPathAttributeAsPath(params), nil |
| 39 | case *api.Attribute_NextHop: |
| 40 | addr, err := netip.ParseAddr(a.NextHop.NextHop) |
| 41 | if err != nil { |
| 42 | return nil, err |
| 43 | } |
| 44 | return bgp.NewPathAttributeNextHop(addr) |
| 45 | case *api.Attribute_MultiExitDisc: |
| 46 | return bgp.NewPathAttributeMultiExitDisc(a.MultiExitDisc.Med), nil |
| 47 | case *api.Attribute_LocalPref: |
| 48 | return bgp.NewPathAttributeLocalPref(a.LocalPref.LocalPref), nil |
| 49 | case *api.Attribute_AtomicAggregate: |
| 50 | return bgp.NewPathAttributeAtomicAggregate(), nil |
| 51 | case *api.Attribute_Aggregator: |
| 52 | address, err := netip.ParseAddr(a.Aggregator.Address) |
| 53 | if err != nil || !address.Is4() { |
| 54 | return nil, fmt.Errorf("invalid aggregator address: %s", a.Aggregator.Address) |
| 55 | } |
| 56 | return bgp.NewPathAttributeAggregator(a.Aggregator.Asn, address) |
| 57 | case *api.Attribute_Communities: |
| 58 | return bgp.NewPathAttributeCommunities(a.Communities.Communities), nil |
| 59 | case *api.Attribute_OriginatorId: |
| 60 | id, err := netip.ParseAddr(a.OriginatorId.Id) |
| 61 | if err != nil || !id.Is4() { |
| 62 | return nil, fmt.Errorf("invalid originator id: %s", a.OriginatorId.Id) |
| 63 | } |
| 64 | return bgp.NewPathAttributeOriginatorId(id) |
| 65 | case *api.Attribute_ClusterList: |
| 66 | l := make([]netip.Addr, 0, len(a.ClusterList.Ids)) |
| 67 | for _, id := range a.ClusterList.Ids { |
| 68 | if i, err := netip.ParseAddr(id); err != nil || !i.Is4() { |
| 69 | return nil, fmt.Errorf("invalid cluster list: %s", a.ClusterList.Ids) |
| 70 | } else { |
| 71 | l = append(l, i) |
| 72 | } |
| 73 | } |
| 74 | return bgp.NewPathAttributeClusterList(l) |
| 75 | case *api.Attribute_MpReach: |
| 76 | if a.MpReach.Family == nil { |
| 77 | return nil, fmt.Errorf("empty family") |
| 78 | } |
| 79 | rf := ToFamily(a.MpReach.Family) |
| 80 | nlris, err := UnmarshalNLRIs(rf, a.MpReach.Nlris) |
| 81 | if err != nil { |
| 82 | return nil, err |
| 83 | } |
| 84 | nexthop := netip.IPv4Unspecified() |
| 85 | var linkLocalNexthop netip.Addr |
| 86 | if rf.Afi() == bgp.AFI_IP6 { |
searching dependent graphs…