func (peer *Peer) filterpath(path *table.Path) *table.Path { // special handling for RTC nlri // see comments in (*Destination).Calculate() if path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC && !path.IsWithdraw { // if we already sent the same nlri, ignore this if peer.adjRibOut.Exists(path) { return nil } dst := peer.localRib.GetDestination(path) path = nil // we send a path even if it is not a best path for _, p := range dst.GetKnownPathList(peer.TableID()) { // just take care not to send back it if peer.ID() != p.GetSource().Address.String() { path = p break } } } if filterpath(peer, path) == nil { return nil } if !peer.isRouteServerClient() { path = path.Clone(path.IsWithdraw) path.UpdatePathAttrs(peer.fsm.gConf, peer.fsm.pConf) } options := &table.PolicyOptions{ Info: peer.fsm.peerInfo, } path = peer.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_EXPORT, path, options) // remove local-pref attribute // we should do this after applying export policy since policy may // set local-preference if path != nil && peer.fsm.pConf.Config.PeerType == config.PEER_TYPE_EXTERNAL { path.RemoveLocalPref() } return path }
func (peer *Peer) filterpath(path, old *table.Path) *table.Path { // special handling for RTC nlri // see comments in (*Destination).Calculate() if path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC && !path.IsWithdraw { // If we already sent the same nlri, send unnecessary // update. Fix this after the API change between table // and server packages. dst := peer.localRib.GetDestination(path) path = nil // we send a path even if it is not a best path for _, p := range dst.GetKnownPathList(peer.TableID()) { // just take care not to send back it if peer.ID() != p.GetSource().Address.String() { path = p break } } } // only allow vpnv4 and vpnv6 paths to be advertised to VRFed neighbors. // also check we can import this path using table.CanImportToVrf() // if we can, make it local path by calling (*Path).ToLocal() if path != nil && peer.fsm.pConf.Config.Vrf != "" { if f := path.GetRouteFamily(); f != bgp.RF_IPv4_VPN && f != bgp.RF_IPv6_VPN { return nil } vrf := peer.localRib.Vrfs[peer.fsm.pConf.Config.Vrf] if table.CanImportToVrf(vrf, path) { path = path.ToLocal() } else { return nil } } if path = filterpath(peer, path, old); path == nil { return nil } path = path.Clone(path.IsWithdraw) path.UpdatePathAttrs(peer.fsm.gConf, peer.fsm.pConf) options := &table.PolicyOptions{ Info: peer.fsm.peerInfo, } path = peer.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_EXPORT, path, options) // draft-uttaro-idr-bgp-persistence-02 // 4.3. Processing LLGR_STALE Routes // // The route SHOULD NOT be advertised to any neighbor from which the // Long-lived Graceful Restart Capability has not been received. The // exception is described in the Optional Partial Deployment // Procedure section (Section 4.7). Note that this requirement // implies that such routes should be withdrawn from any such neighbor. if path != nil && !path.IsWithdraw && !peer.isLLGREnabledFamily(path.GetRouteFamily()) && path.IsLLGRStale() { // we send unnecessary withdrawn even if we didn't // sent the route. path = path.Clone(true) } // remove local-pref attribute // we should do this after applying export policy since policy may // set local-preference if path != nil && !peer.isIBGPPeer() && !peer.isRouteServerClient() { path.RemoveLocalPref() } return path }