MCPcopy
hub / github.com/osrg/gobgp / prePolicyFilterpath

Method prePolicyFilterpath

pkg/server/server.go:584–679  ·  view source on GitHub ↗
(peer *peer, path, old *table.Path)

Source from the content-addressed store, hash-verified

582}
583
584func (s *BgpServer) prePolicyFilterpath(peer *peer, path, old *table.Path) (*table.Path, *table.PolicyOptions, bool) {
585 // Special handling for RTM NLRI.
586 if path != nil && path.GetFamily() == bgp.RF_RTC_UC && !path.IsWithdraw {
587 // If the given "path" is locally generated and the same with "old", we
588 // assumes "path" was already sent before. This assumption avoids the
589 // infinite UPDATE loop between Route Reflector and its clients.
590 if path.IsLocal() && path.Equal(old) {
591 s.logger.Debug("given rtm nlri is already sent, skipping to advertise", slog.Any("Path", path))
592 return nil, nil, true
593 }
594
595 if old != nil && old.IsLocal() {
596 // If it is vrf or rtc route deleting, it will work via explicitWithdraw
597 // and make old.Clone(true). The only way to get path != nil and old != nil
598 // is to change the path without changing rt. Then we need to update path or
599 // do nothing if path == old.
600 } else if peer.isRouteReflectorClient() {
601 // We need to send the path even if the peer is originator of the
602 // path in order to signal that the client should distribute route
603 // with the given RT.
604 } else {
605 // We send a path even if it is not the best path. See comments in
606 // (*Destination) GetChanges().
607 dst := peer.localRib.GetDestination(path)
608 path = nil
609 for _, p := range dst.GetKnownPathList(peer.TableID(), peer.AS()) {
610 srcPeer := p.GetSource()
611 if peer.ID() != srcPeer.Address.String() {
612 if srcPeer.RouteReflectorClient {
613 // The path from a RR client is preferred than others
614 // for the case that RR and non RR client peering
615 // (e.g., peering of different RR clusters).
616 path = p
617 break
618 } else if path == nil {
619 path = p
620 }
621 }
622 }
623 }
624 }
625
626 // only allow vpnv4 and vpnv6 paths to be advertised to VRFed neighbors.
627 // also check we can import this path using table.CanImportToVrf()
628 // if we can, make it local path by calling (*Path).ToLocal()
629 conf := peer.fsm.pConf.ReadOnly()
630 peerVrf := conf.Config.Vrf
631 if path != nil && peerVrf != "" {
632 if f := path.GetFamily(); f != bgp.RF_IPv4_VPN && f != bgp.RF_IPv6_VPN && f != bgp.RF_FS_IPv4_VPN && f != bgp.RF_FS_IPv6_VPN {
633 return nil, nil, true
634 }
635 vrf, ok := peer.localRib.GetVrf(peerVrf)
636 if !ok {
637 return nil, nil, true
638 }
639 if table.CanImportToVrf(vrf, path) {
640 path = path.ToLocal()
641 } else {

Callers 3

filterpathMethod · 0.95
sendSecondaryRoutesMethod · 0.95
getAdjRibMethod · 0.95

Calls 15

CanImportToVrfFunction · 0.92
UpdatePathAttrsFunction · 0.92
filterpathFunction · 0.85
IsLocalMethod · 0.80
TableIDMethod · 0.80
ASMethod · 0.80
GetSourceMethod · 0.80
IDMethod · 0.80
ReadOnlyMethod · 0.80
ToLocalMethod · 0.80
ReplaceASMethod · 0.80

Tested by

no test coverage detected