mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-04 04:49:59 +00:00
zebra: install flood FDB entry only if the remote VTEP asked for HER
Remote VTEPs advertise the flood mode via IMET and the ingress VTEP needs to perform head-end-replication of BUM packets to it only if the PMSI tunnel type is set to ingress-replication. If a type-3 route is not rxed or rxed with a mode other than ingress-replication we can skip installation of the flood fdb entry for that L2-VNI. In that case the remote VTEP is either not interested in BUM traffic or is using a "static-config" based replication mode like PIM. Sample output with HER - ======================= root@TORS1:~# vtysh -c "show evpn vni 1000" |grep "Remote\|flood" Remote VTEPs for this VNI: 27.0.0.8 flood: HER root@TORS1:~# Sample output with PIM-SM - ========================= root@TORS2:~# vtysh -c "show evpn vni 1000" |grep "Remote\|flood" Remote VTEPs for this VNI: 27.0.0.7 flood: - root@TORS2:~# Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
b16dd0191c
commit
9718c54ef4
@ -60,6 +60,16 @@ DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
|
||||
|
||||
/* definitions */
|
||||
/* PMSI strings. */
|
||||
#define VXLAN_FLOOD_STR_NO_INFO "-"
|
||||
#define VXLAN_FLOOD_STR_DEFAULT VXLAN_FLOOD_STR_NO_INFO
|
||||
static const struct message zvtep_flood_str[] = {
|
||||
{VXLAN_FLOOD_DISABLED, VXLAN_FLOOD_STR_NO_INFO},
|
||||
{VXLAN_FLOOD_PIM_SM, "PIM-SM"},
|
||||
{VXLAN_FLOOD_HEAD_END_REPL, "HER"},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
/* static function declarations */
|
||||
static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
|
||||
@ -167,10 +177,11 @@ static int zvni_send_del_to_client(vni_t vni);
|
||||
static void zvni_build_hash_table(void);
|
||||
static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
|
||||
static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
|
||||
static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
|
||||
static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip,
|
||||
int flood_control);
|
||||
static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
|
||||
static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
|
||||
static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
|
||||
static int zvni_vtep_install(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
|
||||
static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
|
||||
static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
|
||||
static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
|
||||
@ -1882,14 +1893,19 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt)
|
||||
else
|
||||
json_vtep_list = json_object_new_array();
|
||||
for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
|
||||
if (json == NULL)
|
||||
vty_out(vty, " %s\n",
|
||||
inet_ntoa(zvtep->vtep_ip));
|
||||
else {
|
||||
const char *flood_str = lookup_msg(zvtep_flood_str,
|
||||
zvtep->flood_control,
|
||||
VXLAN_FLOOD_STR_DEFAULT);
|
||||
|
||||
if (json == NULL) {
|
||||
vty_out(vty, " %s flood: %s\n",
|
||||
inet_ntoa(zvtep->vtep_ip),
|
||||
flood_str);
|
||||
} else {
|
||||
json_ip_str = json_object_new_string(
|
||||
inet_ntoa(zvtep->vtep_ip));
|
||||
inet_ntoa(zvtep->vtep_ip));
|
||||
json_object_array_add(json_vtep_list,
|
||||
json_ip_str);
|
||||
json_ip_str);
|
||||
}
|
||||
}
|
||||
if (json)
|
||||
@ -4092,13 +4108,16 @@ static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
|
||||
/*
|
||||
* Add remote VTEP to VNI hash table.
|
||||
*/
|
||||
static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
|
||||
static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip,
|
||||
int flood_control)
|
||||
|
||||
{
|
||||
zebra_vtep_t *zvtep;
|
||||
|
||||
zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
|
||||
|
||||
zvtep->vtep_ip = *vtep_ip;
|
||||
zvtep->flood_control = flood_control;
|
||||
|
||||
if (zvni->vteps)
|
||||
zvni->vteps->prev = zvtep;
|
||||
@ -4148,12 +4167,15 @@ static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
|
||||
}
|
||||
|
||||
/*
|
||||
* Install remote VTEP into the kernel.
|
||||
* Install remote VTEP into the kernel if the remote VTEP has asked
|
||||
* for head-end-replication.
|
||||
*/
|
||||
static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
|
||||
static int zvni_vtep_install(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
|
||||
{
|
||||
if (is_vxlan_flooding_head_end())
|
||||
return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
|
||||
if (is_vxlan_flooding_head_end() &&
|
||||
(zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL))
|
||||
return kernel_add_vtep(zvni->vni, zvni->vxlan_if,
|
||||
&zvtep->vtep_ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4187,7 +4209,7 @@ static void zvni_handle_flooding_remote_vteps(struct hash_bucket *bucket,
|
||||
|
||||
for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
|
||||
if (is_vxlan_flooding_head_end())
|
||||
zvni_vtep_install(zvni, &zvtep->vtep_ip);
|
||||
zvni_vtep_install(zvni, zvtep);
|
||||
else
|
||||
zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
|
||||
}
|
||||
@ -5165,7 +5187,8 @@ static void process_remote_macip_add(vni_t vni,
|
||||
*/
|
||||
zvtep = zvni_vtep_find(zvni, &vtep_ip);
|
||||
if (!zvtep) {
|
||||
if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
|
||||
zvtep = zvni_vtep_add(zvni, &vtep_ip, VXLAN_FLOOD_DISABLED);
|
||||
if (!zvtep) {
|
||||
flog_err(
|
||||
EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
|
||||
@ -5173,7 +5196,7 @@ static void process_remote_macip_add(vni_t vni,
|
||||
return;
|
||||
}
|
||||
|
||||
zvni_vtep_install(zvni, &vtep_ip);
|
||||
zvni_vtep_install(zvni, zvtep);
|
||||
}
|
||||
|
||||
sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
|
||||
@ -7880,6 +7903,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||
zebra_vni_t *zvni;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
int flood_control;
|
||||
zebra_vtep_t *zvtep;
|
||||
|
||||
if (!is_evpn_enabled()) {
|
||||
zlog_debug(
|
||||
@ -7901,12 +7926,13 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||
STREAM_GETL(s, vni);
|
||||
l += 4;
|
||||
STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
|
||||
STREAM_GETL(s, flood_control);
|
||||
l += IPV4_MAX_BYTELEN;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
|
||||
inet_ntoa(vtep_ip), vni,
|
||||
zebra_route_string(client->proto));
|
||||
zlog_debug("Recv VTEP_ADD %s VNI %u flood %d from %s",
|
||||
inet_ntoa(vtep_ip), vni, flood_control,
|
||||
zebra_route_string(client->proto));
|
||||
|
||||
/* Locate VNI hash entry - expected to exist. */
|
||||
zvni = zvni_lookup(vni);
|
||||
@ -7933,19 +7959,31 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||
continue;
|
||||
|
||||
/* If the remote VTEP already exists,
|
||||
there's nothing more to do. */
|
||||
if (zvni_vtep_find(zvni, &vtep_ip))
|
||||
continue;
|
||||
|
||||
if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
|
||||
flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to add remote VTEP, VNI %u zvni %p",
|
||||
vni, zvni);
|
||||
continue;
|
||||
zvtep = zvni_vtep_find(zvni, &vtep_ip);
|
||||
if (zvtep) {
|
||||
/* If the remote VTEP already exists check if
|
||||
* the flood mode has changed
|
||||
*/
|
||||
if (zvtep->flood_control != flood_control) {
|
||||
if (zvtep->flood_control
|
||||
== VXLAN_FLOOD_DISABLED)
|
||||
/* old mode was head-end-replication but
|
||||
* is no longer; get rid of the HER fdb
|
||||
* entry installed before
|
||||
*/
|
||||
zvni_vtep_uninstall(zvni, &vtep_ip);
|
||||
zvtep->flood_control = flood_control;
|
||||
zvni_vtep_install(zvni, zvtep);
|
||||
}
|
||||
} else {
|
||||
zvtep = zvni_vtep_add(zvni, &vtep_ip, flood_control);
|
||||
if (zvtep)
|
||||
zvni_vtep_install(zvni, zvtep);
|
||||
else
|
||||
flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to add remote VTEP, VNI %u zvni %p",
|
||||
vni, zvni);
|
||||
}
|
||||
|
||||
zvni_vtep_install(zvni, &vtep_ip);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
|
||||
@ -52,6 +52,10 @@ struct zebra_vtep_t_ {
|
||||
/* Remote IP. */
|
||||
/* NOTE: Can only be IPv4 right now. */
|
||||
struct in_addr vtep_ip;
|
||||
/* Flood mode (one of enum vxlan_flood_control) based on the PMSI
|
||||
* tunnel type advertised by the remote VTEP
|
||||
*/
|
||||
int flood_control;
|
||||
|
||||
/* Links. */
|
||||
struct zebra_vtep_t_ *next;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user