summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-03-19 10:37:22 -0700
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-04-20 08:33:20 -0700
commit9718c54ef44f46e97ecb4aa4c570f4337113322c (patch)
tree2f05d96d0e0f33914029755adfa81805425306ca
parentb16dd0191caead2a76db05a1261f18e5af68dc10 (diff)
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>
-rw-r--r--zebra/zebra_vxlan.c100
-rw-r--r--zebra/zebra_vxlan_private.h4
2 files changed, 73 insertions, 31 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 87b279d3d3..461f9dd0ad 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -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:
diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h
index 96e135c188..40e7640cd1 100644
--- a/zebra/zebra_vxlan_private.h
+++ b/zebra/zebra_vxlan_private.h
@@ -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;