summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2018-10-12 22:52:21 +0200
committerGitHub <noreply@github.com>2018-10-12 22:52:21 +0200
commit5d3a8c513fc78d5d22d95b2b90470bce4e1525f4 (patch)
treeec84871a12f9324b12fef1cf867d10682c910ed1 /zebra
parentMerge pull request #3168 from adharkar/frr-bgp_json (diff)
parentbgpd: Add '[no] flood <disable|head-end-replication>' (diff)
downloadfrr-5d3a8c513fc78d5d22d95b2b90470bce4e1525f4.tar.xz
frr-5d3a8c513fc78d5d22d95b2b90470bce4e1525f4.zip
Merge pull request #3134 from donaldsharp/bum_flooding
Bum flooding control for BGP and Zebra
Diffstat (limited to 'zebra')
-rw-r--r--zebra/zapi_msg.c1
-rw-r--r--zebra/zebra_vrf.h7
-rw-r--r--zebra/zebra_vxlan.c78
-rw-r--r--zebra/zebra_vxlan.h10
4 files changed, 93 insertions, 3 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index c193a0c47..149d2cb6a 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2439,6 +2439,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_IPSET_ENTRY_DELETE] = zread_ipset_entry,
[ZEBRA_IPTABLE_ADD] = zread_iptable,
[ZEBRA_IPTABLE_DELETE] = zread_iptable,
+ [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
};
#if defined(HANDLE_ZAPI_FUZZING)
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 78f6331d0..a39d74b08 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -22,6 +22,8 @@
#if !defined(__ZEBRA_VRF_H__)
#define __ZEBRA_VRF_H__
+#include "vxlan.h"
+
#include <zebra/zebra_ns.h>
#include <zebra/zebra_pw.h>
#include <lib/vxlan.h>
@@ -123,6 +125,11 @@ struct zebra_vrf {
/* l3-vni info */
vni_t l3vni;
+ /*
+ * Flooding mechanism for BUM packets for VxLAN-EVPN.
+ */
+ enum vxlan_flood_control vxlan_flood_ctrl;
+
/* Route Installs */
uint64_t installs;
uint64_t removals;
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index f8417503e..5078eff59 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -3097,7 +3097,9 @@ 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)
{
- return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
+ if (is_vxlan_flooding_head_end())
+ return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
+ return 0;
}
/*
@@ -3115,6 +3117,28 @@ static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
}
/*
+ * Install or uninstall flood entries in the kernel corresponding to
+ * remote VTEPs. This is invoked upon change to BUM handling.
+ */
+static void zvni_handle_flooding_remote_vteps(struct hash_backet *backet,
+ void *zvrf)
+{
+ zebra_vni_t *zvni;
+ zebra_vtep_t *zvtep;
+
+ zvni = (zebra_vni_t *)backet->data;
+ if (!zvni)
+ return;
+
+ for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
+ if (is_vxlan_flooding_head_end())
+ zvni_vtep_install(zvni, &zvtep->vtep_ip);
+ else
+ zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
+ }
+}
+
+/*
* Cleanup VNI/VTEP and update kernel
*/
static void zvni_cleanup_all(struct hash_backet *backet, void *arg)
@@ -6898,6 +6922,46 @@ int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
}
/*
+ * Handle message from client to specify the flooding mechanism for
+ * BUM packets. The default is to do head-end (ingress) replication
+ * and the other supported option is to disable it. This applies to
+ * all BUM traffic and disabling it applies to both the transmit and
+ * receive direction.
+ */
+void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
+{
+ struct stream *s;
+ enum vxlan_flood_control flood_ctrl;
+
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("EVPN flood control for non-default VRF %u",
+ zvrf_id(zvrf));
+ return;
+ }
+
+ s = msg;
+ STREAM_GETC(s, flood_ctrl);
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("EVPN flood control %u, currently %u",
+ flood_ctrl, zvrf->vxlan_flood_ctrl);
+
+ if (zvrf->vxlan_flood_ctrl == flood_ctrl)
+ return;
+
+ zvrf->vxlan_flood_ctrl = flood_ctrl;
+
+ /* Install or uninstall flood entries corresponding to
+ * remote VTEPs.
+ */
+ hash_iterate(zvrf->vni_table, zvni_handle_flooding_remote_vteps,
+ zvrf);
+
+stream_failure:
+ return;
+}
+
+/*
* Handle message from client to enable/disable advertisement of g/w macip
* routes
*/
@@ -7073,12 +7137,15 @@ stream_failure:
* When enabled, the VNI hash table will be built and MAC FDB table read;
* when disabled, the entries should be deleted and remote VTEPs and MACs
* uninstalled from the kernel.
+ * This also informs the setting for BUM handling at the time this change
+ * occurs; it is relevant only when specifying "learn".
*/
void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
{
struct stream *s = NULL;
int advertise = 0;
struct zebra_ns *zns = NULL;
+ enum vxlan_flood_control flood_ctrl;
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_debug("EVPN VNI Adv for non-default VRF %u",
@@ -7088,17 +7155,22 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
s = msg;
STREAM_GETC(s, advertise);
+ STREAM_GETC(s, flood_ctrl);
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("EVPN VNI Adv %s, currently %s",
+ zlog_debug("EVPN VNI Adv %s, currently %s, flood control %u",
advertise ? "enabled" : "disabled",
- is_evpn_enabled() ? "enabled" : "disabled");
+ is_evpn_enabled() ? "enabled" : "disabled",
+ flood_ctrl);
if (zvrf->advertise_all_vni == advertise)
return;
zvrf->advertise_all_vni = advertise;
if (is_evpn_enabled()) {
+ /* Note BUM handling */
+ zvrf->vxlan_flood_ctrl = flood_ctrl;
+
/* Build VNI hash table and inform BGP. */
zvni_build_hash_table();
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index a6c668785..f03cd3d54 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -44,6 +44,15 @@ static inline int is_evpn_enabled()
return zvrf ? zvrf->advertise_all_vni : 0;
}
+static inline int
+is_vxlan_flooding_head_end()
+{
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+
+ if (!zvrf)
+ return 0;
+ return (zvrf->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL);
+}
/* VxLAN interface change flags of interest. */
#define ZEBRA_VXLIF_LOCAL_IP_CHANGE 0x1
@@ -57,6 +66,7 @@ extern void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS);