summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c75
-rw-r--r--bgpd/bgp_evpn.h2
-rw-r--r--bgpd/bgpd.c8
3 files changed, 85 insertions, 0 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index c787e21e83..77dc2f2bc7 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1762,6 +1762,61 @@ delete_withdraw_vni_routes (struct bgp *bgp, struct bgpevpn *vpn)
}
/*
+ * Handle router-id change. Update and advertise local routes corresponding
+ * to this VNI from peers. Note that this is invoked after updating the
+ * router-id. The routes in the per-VNI table are used to create routes in
+ * the global table and schedule them.
+ */
+static void
+update_router_id_vni (struct hash_backet *backet, struct bgp *bgp)
+{
+ struct bgpevpn *vpn;
+
+ vpn = (struct bgpevpn *) backet->data;
+
+ if (!vpn)
+ {
+ zlog_warn ("%s: VNI hash entry for VNI not found",
+ __FUNCTION__);
+ return;
+ }
+
+ /* Skip VNIs with configured RD. */
+ if (is_rd_configured (vpn))
+ return;
+
+ bgp_evpn_derive_auto_rd (bgp, vpn);
+ update_advertise_vni_routes (bgp, vpn);
+}
+
+/*
+ * Handle router-id change. Delete and withdraw local routes corresponding
+ * to this VNI from peers. Note that this is invoked prior to updating
+ * the router-id and is done only on the global route table, the routes
+ * are needed in the per-VNI table to re-advertise with new router id.
+ */
+static void
+withdraw_router_id_vni (struct hash_backet *backet, struct bgp *bgp)
+{
+ struct bgpevpn *vpn;
+
+ vpn = (struct bgpevpn *) backet->data;
+
+ if (!vpn)
+ {
+ zlog_warn ("%s: VNI hash entry for VNI not found",
+ __FUNCTION__);
+ return;
+ }
+
+ /* Skip VNIs with configured RD. */
+ if (is_rd_configured (vpn))
+ return;
+
+ delete_withdraw_vni_routes (bgp, vpn);
+}
+
+/*
* Process received EVPN type-2 route (advertise or withdraw).
*/
static int
@@ -2107,6 +2162,26 @@ free_vni_entry (struct hash_backet *backet, struct bgp *bgp)
*/
/*
+ * Handle change to BGP router id. This is invoked twice by the change
+ * handler, first before the router id has been changed and then after
+ * the router id has been changed. The first invocation will result in
+ * local routes for all VNIs being deleted and withdrawn and the next
+ * will result in the routes being re-advertised.
+ */
+void
+bgp_evpn_handle_router_id_update (struct bgp *bgp, int withdraw)
+{
+ if (withdraw)
+ hash_iterate (bgp->vnihash,
+ (void (*) (struct hash_backet *, void *))
+ withdraw_router_id_vni, bgp);
+ else
+ hash_iterate (bgp->vnihash,
+ (void (*) (struct hash_backet *, void *))
+ update_router_id_vni, bgp);
+}
+
+/*
* Handle change to export RT - update and advertise local routes.
*/
int
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index 1a71ec284a..610710d845 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -25,6 +25,8 @@
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
+extern void
+bgp_evpn_handle_router_id_update (struct bgp *bgp, int withdraw);
extern char *
bgp_evpn_label2str (mpls_label_t *label, char *buf, int len);
extern char *
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 723742eb3d..3a4a3e6760 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -227,6 +227,10 @@ bgp_router_id_set (struct bgp *bgp, const struct in_addr *id)
if (IPV4_ADDR_SAME (&bgp->router_id, id))
return 0;
+ /* EVPN uses router id in RD, withdraw them */
+ if (bgp->advertise_all_vni)
+ bgp_evpn_handle_router_id_update (bgp, TRUE);
+
IPV4_ADDR_COPY (&bgp->router_id, id);
/* Set all peer's local identifier with this value. */
@@ -242,6 +246,10 @@ bgp_router_id_set (struct bgp *bgp, const struct in_addr *id)
}
}
+ /* EVPN uses router id in RD, update them */
+ if (bgp->advertise_all_vni)
+ bgp_evpn_handle_router_id_update (bgp, FALSE);
+
return 0;
}