mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 04:14:19 +00:00
bgpd: Add CLI for overlay index recursive resolution
Gateway IP overlay index of the remote type-5 route is resolved recursively using remote type-2 route. For the purpose of this recursive resolution, for each L2VNI, we build a hash table of the remote IP addresses received by remote type-2 routes. For the topologies where overlay index resolution is not needed, we do not need to build this remote-ip-hash. Thus, make the recursive resolution of the overlay index conditional on "enable-resolve-overlay-index" configuration. router bgp 65001 bgp router-id 192.168.100.1 neighbor 10.0.1.2 remote-as 65002 ! address-family l2vpn evpn neighbor 10.0.1.2 activate advertise-all-vni enable-resolve-overlay-index----------> New configuration exit-address-family Gateway IP overlay index will be resolved only if this configuration is present. Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
This commit is contained in:
parent
021b659665
commit
dc6cef732e
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user