func NewRib(seq uint32, prefix bgp.AddrPrefixInterface, entries []*RibEntry) *Rib { rf := bgp.AfiSafiToRouteFamily(prefix.AFI(), prefix.SAFI()) return &Rib{ SequenceNumber: seq, Prefix: prefix, Entries: entries, RouteFamily: rf, } }
func NewDestination(nlri bgp.AddrPrefixInterface) *Destination { d := &Destination{ routeFamily: bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI()), nlri: nlri, knownPathList: make([]*Path, 0), withdrawList: make([]*Path, 0), newPathList: make([]*Path, 0), } switch d.routeFamily { case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: d.RadixKey = CidrToRadixkey(nlri.String()) } return d }
func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pattrs []bgp.PathAttributeInterface, timestamp time.Time, noImplicitWithdraw bool) *Path { if !isWithdraw && pattrs == nil { log.WithFields(log.Fields{ "Topic": "Table", "Key": nlri.String(), "Peer": source.Address.String(), }).Error("Need to provide patattrs for the path that is not withdraw.") return nil } if nlri != nil && (nlri.SAFI() == bgp.SAFI_FLOW_SPEC_UNICAST || nlri.SAFI() == bgp.SAFI_FLOW_SPEC_VPN) { var coms FlowSpecComponents var f *bgp.FlowSpecNLRI switch nlri.(type) { case *bgp.FlowSpecIPv4Unicast: f = &nlri.(*bgp.FlowSpecIPv4Unicast).FlowSpecNLRI case *bgp.FlowSpecIPv4VPN: f = &nlri.(*bgp.FlowSpecIPv4VPN).FlowSpecNLRI case *bgp.FlowSpecIPv6Unicast: f = &nlri.(*bgp.FlowSpecIPv6Unicast).FlowSpecNLRI case *bgp.FlowSpecIPv6VPN: f = &nlri.(*bgp.FlowSpecIPv6VPN).FlowSpecNLRI } if f != nil { coms = f.Value sort.Sort(coms) } } return &Path{ info: &originInfo{ nlri: nlri, source: source, timestamp: timestamp, noImplicitWithdraw: noImplicitWithdraw, }, IsWithdraw: isWithdraw, pathAttrs: pattrs, filtered: make(map[string]PolicyDirection), } }
func (s *Server) api2PathList(resource Resource, ApiPathList []*Path) ([]*table.Path, error) { var nlri bgp.AddrPrefixInterface var nexthop string var pi *table.PeerInfo pathList := make([]*table.Path, 0, len(ApiPathList)) for _, path := range ApiPathList { seen := make(map[bgp.BGPAttrType]bool) pattr := make([]bgp.PathAttributeInterface, 0) extcomms := make([]bgp.ExtendedCommunityInterface, 0) if path.SourceAsn != 0 { pi = &table.PeerInfo{ AS: path.SourceAsn, LocalID: net.ParseIP(path.SourceId), } } if len(path.Nlri) > 0 { nlri = &bgp.IPAddrPrefix{} err := nlri.DecodeFromBytes(path.Nlri) if err != nil { return nil, err } } for _, attr := range path.Pattrs { p, err := bgp.GetPathAttribute(attr) if err != nil { return nil, err } err = p.DecodeFromBytes(attr) if err != nil { return nil, err } if _, ok := seen[p.GetType()]; !ok { seen[p.GetType()] = true } else { return nil, fmt.Errorf("the path attribute apears twice. Type : " + strconv.Itoa(int(p.GetType()))) } switch p.GetType() { case bgp.BGP_ATTR_TYPE_NEXT_HOP: nexthop = p.(*bgp.PathAttributeNextHop).Value.String() case bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: value := p.(*bgp.PathAttributeExtendedCommunities).Value if len(value) > 0 { extcomms = append(extcomms, value...) } case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: mpreach := p.(*bgp.PathAttributeMpReachNLRI) if len(mpreach.Value) != 1 { return nil, fmt.Errorf("include only one route in mp_reach_nlri") } nlri = mpreach.Value[0] nexthop = mpreach.Nexthop.String() default: pattr = append(pattr, p) } } if nlri == nil || nexthop == "" { return nil, fmt.Errorf("not found nlri or nexthop") } rf := bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI()) if resource != Resource_VRF && rf == bgp.RF_IPv4_UC { pattr = append(pattr, bgp.NewPathAttributeNextHop(nexthop)) } else { pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})) } if len(extcomms) > 0 { pattr = append(pattr, bgp.NewPathAttributeExtendedCommunities(extcomms)) } newPath := table.NewPath(pi, nlri, path.IsWithdraw, pattr, time.Now(), path.NoImplicitWithdraw) newPath.SetIsFromExternal(path.IsFromExternal) pathList = append(pathList, newPath) } return pathList, nil }