diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-10-18 11:38:29 +0900 |
---|---|---|
committer | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-11-07 09:55:25 +0900 |
commit | a5715a7bc3c4c73a6f4d3a91980bbfe681969b94 (patch) | |
tree | ee1cefac278e8b9b19d376544bad9895a79d7f78 /server | |
parent | 8f0c42dbfff06f11ef65c14ee23ece050aa38460 (diff) |
server: Avoid local paths left on iBGP peers
Currently, with iBGP peering, the CLI injected path will not be withdrawn
when the deletion if any other path exists on RIB, then the CLI injected
path will be left on iBGP peers even if the route is deleted on the
originator router.
This problem can cause routing loops in some case.
This patch fixes to withdraw the old best path when it was the CLI (or
gRPC) injected path.
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'server')
-rw-r--r-- | server/peer.go | 4 | ||||
-rw-r--r-- | server/server.go | 24 |
2 files changed, 19 insertions, 9 deletions
diff --git a/server/peer.go b/server/peer.go index 84b7268f..892395be 100644 --- a/server/peer.go +++ b/server/peer.go @@ -120,6 +120,10 @@ func NewPeer(g *config.Global, conf *config.Neighbor, loc *table.TableManager, p return peer } +func (peer *Peer) AS() uint32 { + return peer.fsm.pConf.State.PeerAs +} + func (peer *Peer) ID() string { return peer.fsm.pConf.State.NeighborAddress } diff --git a/server/server.go b/server/server.go index ff7fcaf0..18ff196d 100644 --- a/server/server.go +++ b/server/server.go @@ -337,7 +337,7 @@ func sendFsmOutgoingMsg(peer *Peer, paths []*table.Path, notification *bgp.BGPMe func isASLoop(peer *Peer, path *table.Path) bool { for _, as := range path.GetAsList() { - if as == peer.fsm.pConf.State.PeerAs { + if as == peer.AS() { return true } } @@ -378,7 +378,7 @@ func filterpath(peer *Peer, path, old *table.Path) *table.Path { ignore = true info := path.GetSource() //if the path comes from eBGP peer - if info.AS != peer.fsm.pConf.State.PeerAs { + if info.AS != peer.AS() { ignore = false } // RFC4456 8. Avoiding Routing Information Loops @@ -416,13 +416,19 @@ func filterpath(peer *Peer, path, old *table.Path) *table.Path { } if ignore { - if !path.IsWithdraw && old != nil && old.GetSource().Address.String() != peer.ID() && old.GetSource().AS != peer.fsm.pConf.State.PeerAs { - // we advertise a route from ebgp, - // which is the old best. We got the - // new best from ibgp. We don't - // advertise the new best and need to - // withdraw the old. - return old.Clone(true) + if !path.IsWithdraw && old != nil { + oldSource := old.GetSource() + if old.IsLocal() || oldSource.Address.String() != peer.ID() && oldSource.AS != peer.AS() { + // In this case, we suppose this peer has the same prefix + // received from another iBGP peer. + // So we withdraw the old best which was injected locally + // (from CLI or gRPC for example) in order to avoid the + // old best left on peers. + // Also, we withdraw the eBGP route which is the old best. + // When we got the new best from iBGP, we don't advertise + // the new best and need to withdraw the old best. + return old.Clone(true) + } } log.WithFields(log.Fields{ "Topic": "Peer", |