summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c86
-rw-r--r--bgpd/bgp_evpn.h14
-rw-r--r--bgpd/bgp_evpn_vty.c44
-rw-r--r--bgpd/bgpd.h9
4 files changed, 139 insertions, 14 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 1db552f11..e08e5b979 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -72,6 +72,10 @@ static void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn,
struct bgp_path_info *pi);
static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn,
struct bgp_path_info *pi);
+static void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn,
+ void (*func)(struct hash_bucket *,
+ void *),
+ void *arg);
static void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn);
static void bgp_evpn_unlink_from_vni_svi_hash(struct bgp *bgp,
struct bgpevpn *vpn);
@@ -5780,9 +5784,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
* Unresolve all the gateway IP nexthops for this VNI
* for old SVI
*/
- hash_iterate(vpn->remote_ip_hash,
- (void (*)(struct hash_bucket *,
- void *))bgp_evpn_remote_ip_hash_unlink_nexthop,
+ bgp_evpn_remote_ip_hash_iterate(
+ vpn,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_remote_ip_hash_unlink_nexthop,
vpn);
bgp_evpn_unlink_from_vni_svi_hash(bgp, vpn);
vpn->svi_ifindex = svi_ifindex;
@@ -5792,9 +5797,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
* Resolve all the gateway IP nexthops for this VNI
* for new SVI
*/
- hash_iterate(vpn->remote_ip_hash,
- (void (*)(struct hash_bucket *,
- void *))bgp_evpn_remote_ip_hash_link_nexthop,
+ bgp_evpn_remote_ip_hash_iterate(
+ vpn,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_remote_ip_hash_link_nexthop,
vpn);
}
@@ -5805,9 +5811,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
* Unresolve all the gateway IP nexthops for this VNI
* in old tenant vrf
*/
- hash_iterate(vpn->remote_ip_hash,
- (void (*)(struct hash_bucket *,
- void *))bgp_evpn_remote_ip_hash_unlink_nexthop,
+ bgp_evpn_remote_ip_hash_iterate(
+ vpn,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_remote_ip_hash_unlink_nexthop,
vpn);
bgpevpn_unlink_from_l3vni(vpn);
vpn->tenant_vrf_id = tenant_vrf_id;
@@ -5817,9 +5824,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
* Resolve all the gateway IP nexthops for this VNI
* in new tenant vrf
*/
- hash_iterate(vpn->remote_ip_hash,
- (void (*)(struct hash_bucket *,
- void *))bgp_evpn_remote_ip_hash_link_nexthop,
+ bgp_evpn_remote_ip_hash_iterate(
+ vpn,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_remote_ip_hash_link_nexthop,
vpn);
}
@@ -6091,6 +6099,9 @@ static bool bgp_evpn_remote_ip_hash_cmp(const void *p1, const void *p2)
static void bgp_evpn_remote_ip_hash_init(struct bgpevpn *vpn)
{
+ if (!evpn_resolve_overlay_index())
+ return;
+
vpn->remote_ip_hash = hash_create(bgp_evpn_remote_ip_hash_key_make,
bgp_evpn_remote_ip_hash_cmp,
"BGP EVPN remote IP hash");
@@ -6111,7 +6122,7 @@ static void bgp_evpn_remote_ip_hash_free(struct hash_bucket *bucket, void *args)
static void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *vpn)
{
- if (vpn->remote_ip_hash == NULL)
+ if (!evpn_resolve_overlay_index() || vpn->remote_ip_hash == NULL)
return;
hash_iterate(vpn->remote_ip_hash,
@@ -6130,6 +6141,13 @@ static void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn,
struct evpn_remote_ip *ip;
struct prefix_evpn *evp;
+ if (!evpn_resolve_overlay_index())
+ return;
+
+ if (pi->type != ZEBRA_ROUTE_BGP || pi->sub_type != BGP_ROUTE_IMPORTED
+ || !CHECK_FLAG(pi->flags, BGP_PATH_VALID))
+ return;
+
evp = (struct prefix_evpn *)&pi->net->p;
if (evp->family != AF_EVPN
@@ -6163,6 +6181,9 @@ static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn,
struct evpn_remote_ip *ip;
struct prefix_evpn *evp;
+ if (!evpn_resolve_overlay_index())
+ return;
+
evp = (struct prefix_evpn *)&pi->net->p;
if (evp->family != AF_EVPN
@@ -6184,6 +6205,17 @@ static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn,
}
}
+static void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn,
+ void (*func)(struct hash_bucket *,
+ void *),
+ void *arg)
+{
+ if (!evpn_resolve_overlay_index())
+ return;
+
+ hash_iterate(vpn->remote_ip_hash, func, arg);
+}
+
static void show_remote_ip_entry(struct hash_bucket *bucket, void *args)
{
char buf[INET6_ADDRSTRLEN];
@@ -6211,7 +6243,8 @@ void bgp_evpn_show_remote_ip_hash(struct hash_bucket *bucket, void *args)
struct vty *vty = (struct vty *)args;
vty_out(vty, "VNI: %u\n", vpn->vni);
- hash_iterate(vpn->remote_ip_hash,
+ bgp_evpn_remote_ip_hash_iterate(
+ vpn,
(void (*)(struct hash_bucket *, void *))show_remote_ip_entry,
vty);
vty_out(vty, "\n");
@@ -6300,6 +6333,9 @@ bool bgp_evpn_is_gateway_ip_resolved(struct bgp_nexthop_cache *bnc)
struct evpn_remote_ip tmp;
struct prefix *p;
+ if (!evpn_resolve_overlay_index())
+ return false;
+
if (!bnc->nexthop || bnc->nexthop->ifindex == 0)
return false;
@@ -6411,3 +6447,25 @@ static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn,
}
}
+void bgp_evpn_handle_resolve_overlay_index_set(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
+ struct bgp_dest *dest;
+ struct bgp_path_info *pi;
+
+ bgp_evpn_remote_ip_hash_init(vpn);
+
+ for (dest = bgp_table_top(vpn->route_table); dest;
+ dest = bgp_route_next(dest))
+ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
+ bgp_evpn_remote_ip_hash_add(vpn, pi);
+}
+
+void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
+
+ bgp_evpn_remote_ip_hash_destroy(vpn);
+}
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index f91b81f10..eec746e3b 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -156,6 +156,14 @@ static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi)
return true;
}
+static inline bool evpn_resolve_overlay_index(void)
+{
+ struct bgp *bgp = NULL;
+
+ bgp = bgp_get_evpn();
+ return bgp ? bgp->resolve_overlay_index : false;
+}
+
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
const struct prefix *p,
struct attr *src_attr, afi_t afi,
@@ -215,5 +223,11 @@ extern void bgp_evpn_show_remote_ip_hash(struct hash_bucket *bucket,
void *args);
extern void bgp_evpn_show_vni_svi_hash(struct hash_bucket *bucket, void *args);
extern bool bgp_evpn_is_gateway_ip_resolved(struct bgp_nexthop_cache *bnc);
+extern void
+bgp_evpn_handle_resolve_overlay_index_set(struct hash_bucket *bucket,
+ void *arg);
+extern void
+bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket,
+ void *arg);
#endif /* _QUAGGA_BGP_EVPN_H */
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index c334992d9..adb7148f2 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3302,6 +3302,28 @@ static void evpn_unset_advertise_all_vni(struct bgp *bgp)
bgp_evpn_cleanup_on_disable(bgp);
}
+/* Set resolve overlay index flag */
+static void bgp_evpn_set_unset_resolve_overlay_index(struct bgp *bgp, bool set)
+{
+ if (set == bgp->resolve_overlay_index)
+ return;
+
+ if (set) {
+ bgp->resolve_overlay_index = true;
+ hash_iterate(bgp->vnihash,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_handle_resolve_overlay_index_set,
+ NULL);
+ } else {
+ hash_iterate(
+ bgp->vnihash,
+ (void (*)(struct hash_bucket *, void *))
+ bgp_evpn_handle_resolve_overlay_index_unset,
+ NULL);
+ bgp->resolve_overlay_index = false;
+ }
+}
+
/*
* EVPN - use RFC8365 to auto-derive RT
*/
@@ -4117,6 +4139,23 @@ DEFPY (bgp_evpn_ead_evi_tx_disable,
return CMD_SUCCESS;
}
+DEFPY (bgp_evpn_enable_resolve_overlay_index,
+ bgp_evpn_enable_resolve_overlay_index_cmd,
+ "[no$no] enable-resolve-overlay-index",
+ NO_STR
+ "Enable Recursive Resolution of type-5 route overlay index\n")
+{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+
+ if (bgp != bgp_get_evpn()) {
+ vty_out(vty, "This command is only supported under EVPN VRF\n");
+ return CMD_WARNING;
+ }
+
+ bgp_evpn_set_unset_resolve_overlay_index(bgp, no ? false : true);
+ return CMD_SUCCESS;
+}
+
DEFPY (bgp_evpn_advertise_pip_ip_mac,
bgp_evpn_advertise_pip_ip_mac_cmd,
"[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]",
@@ -6252,6 +6291,9 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (bgp->evpn_info->advertise_svi_macip)
vty_out(vty, " advertise-svi-ip\n");
+ if (bgp->resolve_overlay_index)
+ vty_out(vty, " enable-resolve-overlay-index\n");
+
if (bgp_mh_info->host_routes_use_l3nhg !=
BGP_EVPN_MH_USE_ES_L3NHG_DEF) {
if (bgp_mh_info->host_routes_use_l3nhg)
@@ -6440,6 +6482,8 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_EVPN_NODE, &bgp_evpn_use_es_l3nhg_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_rx_disable_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_tx_disable_cmd);
+ install_element(BGP_EVPN_NODE,
+ &bgp_evpn_enable_resolve_overlay_index_cmd);
/* test commands */
install_element(BGP_EVPN_NODE, &test_es_add_cmd);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index a43a21e16..776f4b0a2 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -693,6 +693,15 @@ struct bgp {
/* Hash table of EVPN nexthops maintained per-tenant-VRF */
struct hash *evpn_nh_table;
+ /*
+ * Flag resolve_overlay_index is used for recursive resolution
+ * procedures for EVPN type-5 route's gateway IP overlay index.
+ * When this flag is set, we build remote-ip-hash for
+ * all L2VNIs and resolve overlay index nexthops using this hash.
+ * Overlay index nexthops remain unresolved if this flag is not set.
+ */
+ bool resolve_overlay_index;
+
/* vrf flags */
uint32_t vrf_flags;
#define BGP_VRF_AUTO (1 << 0)