summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c36
-rw-r--r--bgpd/bgp_nexthop.c19
-rw-r--r--bgpd/bgp_nexthop.h2
3 files changed, 40 insertions, 17 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index c9e935668e..155e33da91 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -2736,23 +2736,29 @@ static int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn,
* Note: Route re-advertisement happens elsewhere after other processing
* other changes.
*/
-static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
- struct in_addr originator_ip)
+static void handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
+ struct in_addr originator_ip)
{
struct prefix_evpn p;
+ if (IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
+ return;
+
/* If VNI is not live, we only need to update the originator ip */
if (!is_vni_live(vpn)) {
vpn->originator_ip = originator_ip;
- return 0;
+ return;
}
/* 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.
@@ -2762,7 +2768,7 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
/* Update the tunnel IP and re-advertise all routes for this VNI. */
vpn->originator_ip = originator_ip;
- return 0;
+ return;
}
static struct bgp_path_info *
@@ -6545,8 +6551,7 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
/* If tunnel endpoint IP has changed, update (and delete prior
* type-3 route, if needed.)
*/
- if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
- handle_tunnel_ip_change(bgp, vpn, originator_ip);
+ handle_tunnel_ip_change(bgp, vpn, originator_ip);
/* Update all routes with new endpoint IP and/or export RT
* for VRFs
@@ -6567,10 +6572,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.
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index d9822ee974..77e26037c0 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -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)
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index efad906d0a..d765bdd261 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -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);