summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2018-05-16 10:50:38 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-05-23 13:00:33 +0900
commitcb30860d718a9c1c2935ef3c516830cfadeb0b79 (patch)
treebf0f6f3dc712694bb452cb7e4751352538ba4230
parentcb259ecb0f4135694e86c0605a226779ebd6b8f0 (diff)
zclient: Avoid flapping of nexthop reachability
Currently, GoBGP sends the ROUTE_DELETE messages to Zebra for the paths whose nexthop was determined as unreachable by IGP, but when Zebra received the ROUTE_DELETE messages for the unreachable nexthop, Zebra will send the NEXTHOP_UPDATE message with the given nexthop is reachable via the default interface. This message unexpectedly causes updates of the unreachable path to be reachable (not true though). Then GoBGP will send ROUTE_ADD messages to Zebra, but those paths soon will be invalidated via the NEXTHOP_UPDATE message, GoBGP will send the ROUTE_DELETE messages and ... (infinite loop). This patch fixes to avoid sending the ROUTE_DELETE messages for the unreachable paths because those paths are inactivated on Zebra and not installed to FIB. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r--server/zclient.go6
-rw-r--r--table/destination.go16
2 files changed, 16 insertions, 6 deletions
diff --git a/server/zclient.go b/server/zclient.go
index eb3e0b81..5b1ba483 100644
--- a/server/zclient.go
+++ b/server/zclient.go
@@ -210,7 +210,11 @@ func (m *nexthopTrackingManager) filterPathToRegister(paths pathList) pathList {
func filterOutExternalPath(paths pathList) pathList {
filteredPaths := make(pathList, 0, len(paths))
for _, path := range paths {
- if path == nil || path.IsFromExternal() {
+ // Here filters out:
+ // - Nil path
+ // - External path (advertised from Zebra) in order avoid sending back
+ // - Unreachable path because invalidated by Zebra
+ if path == nil || path.IsFromExternal() || path.IsNexthopInvalid {
continue
}
filteredPaths = append(filteredPaths, path)
diff --git a/table/destination.go b/table/destination.go
index e063d89d..adf1c0cd 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -238,16 +238,17 @@ func getBestPath(id string, as uint32, pathList []*Path) *Path {
if rsFilter(id, as, p) {
continue
}
-
- if !p.IsNexthopInvalid {
- return p
- }
+ return p
}
return nil
}
func (dd *Destination) GetBestPath(id string, as uint32) *Path {
- return getBestPath(id, as, dd.knownPathList)
+ p := getBestPath(id, as, dd.knownPathList)
+ if p == nil || p.IsNexthopInvalid {
+ return nil
+ }
+ return p
}
func (dd *Destination) GetMultiBestPath(id string) []*Path {
@@ -573,6 +574,11 @@ func (u *Update) GetChanges(id string, as uint32, peerDown bool) (*Path, *Path,
// For BGP Nexthop Tracking, checks if the nexthop reachability
// was changed or not.
if best.IsNexthopInvalid != old.IsNexthopInvalid {
+ // If the nexthop of the best path became unreachable, we need
+ // to withdraw that path.
+ if best.IsNexthopInvalid {
+ return best.Clone(true), old
+ }
return best, old
}
return nil, old