]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: do not unregister for prefix nexthop updates if nh exists
authorPat Ruddy <pat@voltanet.io>
Fri, 26 Jun 2020 16:37:30 +0000 (17:37 +0100)
committerGalaxyGorilla <sascha@netdef.org>
Mon, 31 Aug 2020 09:11:47 +0000 (09:11 +0000)
since the addition of srte_color to the comparison for bgp nexthops
it is possible to have several nexthops per prefix but since zebra
only sores a per prefix registration we should not unregister for
nh notifications for a prefix unti all the nexthops for that prefix
have been deleted. Otherwise we can get into a deadlock situation
where BGP thinks we have registered but we have unregistered from zebra.

Signed-off-by: Pat Ruddy <pat@voltanet.io>
bgpd/bgp_nexthop.c
bgpd/bgp_nexthop.h
bgpd/bgp_nht.c

index 6f36fd1394c501d6d79f44e28a972a24a71b52fb..ed026a2fffe76afadf980d61b4fefcab017316fa 100644 (file)
@@ -84,6 +84,19 @@ struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
        return bnc;
 }
 
+bool bnc_existing_for_prefix(struct bgp_nexthop_cache *bnc)
+{
+       struct bgp_nexthop_cache *bnc_tmp;
+
+       frr_each (bgp_nexthop_cache, bnc->tree, bnc_tmp) {
+               if (bnc_tmp == bnc)
+                       continue;
+               if (prefix_cmp(&bnc->prefix, &bnc_tmp->prefix) == 0)
+                       return true;
+       }
+       return false;
+}
+
 void bnc_free(struct bgp_nexthop_cache *bnc)
 {
        bnc_nexthop_free(bnc);
index 356af54002cafe765e942e2d67a53a8bb6848fea..c4b913faf4b7cf0b1b0b593dfeae8d4675b967c0 100644 (file)
@@ -118,6 +118,7 @@ extern bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type,
 extern struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
                                         struct prefix *prefix,
                                         uint32_t srte_color);
+extern bool bnc_existing_for_prefix(struct bgp_nexthop_cache *bnc);
 extern void bnc_free(struct bgp_nexthop_cache *bnc);
 extern struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree,
                                          struct prefix *prefix,
index 80ee5f534990d3b21bc4b9799f278e55ff7898a1..9573d118e5a774fd06f138829800d32be523d8a2 100644 (file)
@@ -76,8 +76,10 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
                                   bnc_str(bnc, buf, PREFIX2STR_BUFFER),
                                   bnc->srte_color, bnc->bgp->name_pretty);
                }
-               unregister_zebra_rnh(bnc,
-                                    CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
+               /* only unregister if this is the last nh for this prefix*/
+               if (!bnc_existing_for_prefix(bnc))
+                       unregister_zebra_rnh(
+                               bnc, CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
                bnc_free(bnc);
        }
 }