summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/server/peer.go26
-rw-r--r--pkg/server/server_test.go3
2 files changed, 27 insertions, 2 deletions
diff --git a/pkg/server/peer.go b/pkg/server/peer.go
index a3f2be7b..4a7d5922 100644
--- a/pkg/server/peer.go
+++ b/pkg/server/peer.go
@@ -131,6 +131,15 @@ func (peer *peer) ID() string {
return peer.fsm.pConf.State.NeighborAddress
}
+func (peer *peer) RouterID() string {
+ peer.fsm.lock.RLock()
+ defer peer.fsm.lock.RUnlock()
+ if peer.fsm.peerInfo.ID != nil {
+ return peer.fsm.peerInfo.ID.String()
+ }
+ return ""
+}
+
func (peer *peer) TableID() string {
return peer.tableId
}
@@ -348,7 +357,22 @@ func (peer *peer) stopPeerRestarting() {
}
func (peer *peer) filterPathFromSourcePeer(path, old *table.Path) *table.Path {
- if peer.ID() != path.GetSource().Address.String() {
+ // Consider 3 peers - A, B, C and prefix P originated by C. Parallel eBGP
+ // sessions exist between A & B, and both have a single session with C.
+ //
+ // When A receives the withdraw from C, we enter this func for each peer of
+ // A, with the following:
+ // peer: [C, B #1, B #2]
+ // path: new best for P facing B
+ // old: old best for P facing C
+ //
+ // Our comparison between peer identifier and path source ID must be router
+ // ID-based (not neighbor address), otherwise we will return early. If we
+ // return early for one of the two sessions facing B
+ // (whichever is not the new best path), we fail to send a withdraw towards
+ // B, and the route is "stuck".
+ // TODO: considerations for RFC6286
+ if peer.RouterID() != path.GetSource().ID.String() {
return path
}
diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go
index 6f70f38a..39b10657 100644
--- a/pkg/server/server_test.go
+++ b/pkg/server/server_test.go
@@ -706,10 +706,11 @@ func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (*
nConf,
rib,
policy)
+ p.fsm.peerInfo.ID = net.ParseIP(address)
for _, f := range rib.GetRFlist() {
p.fsm.rfMap[f] = bgp.BGP_ADD_PATH_NONE
}
- return p, &table.PeerInfo{AS: as, Address: net.ParseIP(address)}
+ return p, &table.PeerInfo{AS: as, Address: net.ParseIP(address), ID: net.ParseIP(address)}
}
func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) {