]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: only unimport routes if tunnel-ip changes
authorTrey Aspelund <taspelund@nvidia.com>
Wed, 25 Jan 2023 18:07:43 +0000 (13:07 -0500)
committerTrey Aspelund <taspelund@nvidia.com>
Fri, 27 Jan 2023 16:11:44 +0000 (11:11 -0500)
When processing a new local VNI, we were always walking the global EVPN
table to look for routes that needed to be removed due to a martian
nexthop change (specifically a tunnel-ip change).
Since the martian TIP table is global (all VNIs) + the walk is also in
the global table (all VNIs), we can trust that any new TIP from any VNI
would result in routes getting removed from the global table and
unimported from all live (L2)VNIs.
i.e.
The only time this update is actionable is if we are adding/removing an
IP from the martian TIP table, and we do not need to walk the table for
normal refcount adjustments.

Signed-off-by: Trey Aspelund <taspelund@nvidia.com>
bgpd/bgp_evpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_nexthop.h

index c9e935668e0d6952f1eb448a899631b067b8e8d5..dbd8bebe5a14c883669f1ef4a93cc5dfe3ebb455 100644 (file)
@@ -2749,10 +2749,13 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
 
        /* Update the tunnel-ip hash */
        bgp_tip_del(bgp, &vpn->originator_ip);
-       bgp_tip_add(bgp, &originator_ip);
-
-       /* filter routes as martian nexthop db has changed */
-       bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
+       if (bgp_tip_add(bgp, &originator_ip))
+               /* The originator_ip was not already present in the
+                * bgp martian next-hop table as a tunnel-ip, so we
+                * need to go back and filter routes matching the new
+                * martian next-hop.
+                */
+               bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
 
        /* Need to withdraw type-3 route as the originator IP is part
         * of the key.
@@ -6567,10 +6570,13 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
        SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
 
        /* tunnel is now active, add tunnel-ip to db */
-       bgp_tip_add(bgp, &originator_ip);
-
-       /* filter routes as nexthop database has changed */
-       bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
+       if (bgp_tip_add(bgp, &originator_ip))
+               /* The originator_ip was not already present in the
+                * bgp martian next-hop table as a tunnel-ip, so we
+                * need to go back and filter routes matching the new
+                * martian next-hop.
+                */
+               bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
 
        /*
         * Create EVPN type-3 route and schedule for processing.
index d9822ee9740d5c4a28553cf339a75e0eff39ee66..77e26037c0eea0e918ba809435c0d214c86dcfdf 100644 (file)
@@ -188,15 +188,30 @@ void bgp_tip_hash_destroy(struct bgp *bgp)
        bgp->tip_hash = NULL;
 }
 
-void bgp_tip_add(struct bgp *bgp, struct in_addr *tip)
+/* Add/Update Tunnel-IP entry of bgp martian next-hop table.
+ *
+ * Returns true only if we add a _new_ TIP so the caller knows that an
+ * actionable change has occurred. If we find an existing TIP then we
+ * only need to update the refcnt, since the collection of known TIPs
+ * has not changed.
+ */
+bool bgp_tip_add(struct bgp *bgp, struct in_addr *tip)
 {
        struct tip_addr tmp;
        struct tip_addr *addr;
+       bool tip_added = false;
 
        tmp.addr = *tip;
 
-       addr = hash_get(bgp->tip_hash, &tmp, bgp_tip_hash_alloc);
+       addr = hash_lookup(bgp->tip_hash, &tmp);
+       if (!addr) {
+               addr = hash_get(bgp->tip_hash, &tmp, bgp_tip_hash_alloc);
+               tip_added = true;
+       }
+
        addr->refcnt++;
+
+       return tip_added;
 }
 
 void bgp_tip_del(struct bgp *bgp, struct in_addr *tip)
index efad906d0a90df2ac97e2ea83905841a34376ff5..d765bdd2610842adde448bf426ef19b8b3d4ef61 100644 (file)
@@ -166,7 +166,7 @@ extern void bgp_scan_finish(struct bgp *bgp);
 extern void bgp_scan_vty_init(void);
 extern void bgp_address_init(struct bgp *bgp);
 extern void bgp_address_destroy(struct bgp *bgp);
-extern void bgp_tip_add(struct bgp *bgp, struct in_addr *tip);
+extern bool bgp_tip_add(struct bgp *bgp, struct in_addr *tip);
 extern void bgp_tip_del(struct bgp *bgp, struct in_addr *tip);
 extern void bgp_tip_hash_init(struct bgp *bgp);
 extern void bgp_tip_hash_destroy(struct bgp *bgp);