summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c2
-rw-r--r--bgpd/bgp_evpn_vty.c147
-rw-r--r--bgpd/bgp_zebra.c37
-rw-r--r--bgpd/bgp_zebra.h1
-rw-r--r--lib/log.c1
-rw-r--r--lib/zclient.h1
6 files changed, 189 insertions, 0 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index b3a498bf5..e5e80cd5c 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -5814,6 +5814,8 @@ void bgp_evpn_init(struct bgp *bgp)
bgp->evpn_info->dad_max_moves = EVPN_DAD_DEFAULT_MAX_MOVES;
bgp->evpn_info->dad_freeze = false;
bgp->evpn_info->dad_freeze_time = 0;
+ /* Initialize zebra vxlan */
+ bgp_zebra_dup_addr_detection(bgp);
}
/* Default BUM handling is to do head-end replication. */
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index aa5eabead..729fa6748 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2999,6 +2999,130 @@ DEFUN (no_bgp_evpn_default_originate,
return CMD_SUCCESS;
}
+DEFPY (dup_addr_detection,
+ dup_addr_detection_cmd,
+ "dup-addr-detection [max-moves (2-1000)$max_moves_val time (2-1800)$time_val]",
+ "Duplicate address detection\n"
+ "Max allowed moved before address detected as duplicate\n"
+ "Num of max allowed moves (2-1000) default 5\n"
+ "Duplicate address detection time\n"
+ "Time in seconds (2-1800) default 180\n")
+{
+ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
+
+ if (!bgp_vrf)
+ return CMD_WARNING;
+
+ bgp_vrf->evpn_info->dup_addr_detect = true;
+
+ if (time_val)
+ bgp_vrf->evpn_info->dad_time = time_val;
+ if (max_moves_val)
+ bgp_vrf->evpn_info->dad_max_moves = max_moves_val;
+
+ bgp_zebra_dup_addr_detection(bgp_vrf);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (dup_addr_detection_auto_recovery,
+ dup_addr_detection_auto_recovery_cmd,
+ "dup-addr-detection freeze <permanent |(30-3600)$freeze_time_val>",
+ "Duplicate address detection\n"
+ "Duplicate address detection freeze\n"
+ "Duplicate address detection permanent freeze\n"
+ "Duplicate address detection freeze time (30-3600)\n")
+{
+ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
+ uint32_t freeze_time = freeze_time_val;
+
+ if (!bgp_vrf)
+ return CMD_WARNING;
+
+ bgp_vrf->evpn_info->dup_addr_detect = true;
+ bgp_vrf->evpn_info->dad_freeze = true;
+ bgp_vrf->evpn_info->dad_freeze_time = freeze_time;
+
+ bgp_zebra_dup_addr_detection(bgp_vrf);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_dup_addr_detection,
+ no_dup_addr_detection_cmd,
+ "no dup-addr-detection [max-moves (2-1000)$max_moves_val time (2-1800)$time_val | freeze <permanent$permanent_val | (30-3600)$freeze_time_val>]",
+ NO_STR
+ "Duplicate address detection\n"
+ "Max allowed moved before address detected as duplicate\n"
+ "Num of max allowed moves (2-1000) default 5\n"
+ "Duplicate address detection time\n"
+ "Time in seconds (2-1800) default 180\n"
+ "Duplicate address detection freeze\n"
+ "Duplicate address detection permanent freeze\n"
+ "Duplicate address detection freeze time (30-3600)\n")
+{
+ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
+ uint32_t max_moves = (uint32_t)max_moves_val;
+ uint32_t freeze_time = (uint32_t)freeze_time_val;
+
+ if (!bgp_vrf)
+ return CMD_WARNING;
+
+ if (argc == 2) {
+ if (!bgp_vrf->evpn_info->dup_addr_detect)
+ return CMD_SUCCESS;
+ /* Reset all parameters to default. */
+ bgp_vrf->evpn_info->dup_addr_detect = false;
+ bgp_vrf->evpn_info->dad_time = EVPN_DAD_DEFAULT_TIME;
+ bgp_vrf->evpn_info->dad_max_moves = EVPN_DAD_DEFAULT_MAX_MOVES;
+ bgp_vrf->evpn_info->dad_freeze = false;
+ bgp_vrf->evpn_info->dad_freeze_time = 0;
+ } else {
+ if (max_moves) {
+ if (bgp_vrf->evpn_info->dad_max_moves != max_moves) {
+ vty_out(vty,
+ "%% Value does not match with config\n");
+ return CMD_SUCCESS;
+ }
+ bgp_vrf->evpn_info->dad_max_moves =
+ EVPN_DAD_DEFAULT_MAX_MOVES;
+ }
+
+ if (time_val) {
+ if (bgp_vrf->evpn_info->dad_time != time_val) {
+ vty_out(vty,
+ "%% Value does not match with config\n");
+ return CMD_SUCCESS;
+ }
+ bgp_vrf->evpn_info->dad_time = EVPN_DAD_DEFAULT_TIME;
+ }
+
+ if (freeze_time) {
+ if (bgp_vrf->evpn_info->dad_freeze_time
+ != freeze_time) {
+ vty_out(vty,
+ "%% Value does not match with config\n");
+ return CMD_SUCCESS;
+ }
+ bgp_vrf->evpn_info->dad_freeze_time = 0;
+ bgp_vrf->evpn_info->dad_freeze = false;
+ }
+
+ if (permanent_val) {
+ if (bgp_vrf->evpn_info->dad_freeze_time) {
+ vty_out(vty,
+ "%% Value does not match with config\n");
+ return CMD_SUCCESS;
+ }
+ bgp_vrf->evpn_info->dad_freeze = false;
+ }
+ }
+
+ bgp_zebra_dup_addr_detection(bgp_vrf);
+
+ return CMD_SUCCESS;
+}
+
DEFUN_HIDDEN (bgp_evpn_advertise_vni_subnet,
bgp_evpn_advertise_vni_subnet_cmd,
"advertise-subnet",
@@ -4919,6 +5043,26 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (bgp->advertise_gw_macip)
vty_out(vty, " advertise-default-gw\n");
+ if (!bgp->evpn_info->dup_addr_detect)
+ vty_out(vty, " no dup-addr-detection\n");
+
+ if (bgp->evpn_info->dad_max_moves !=
+ EVPN_DAD_DEFAULT_MAX_MOVES ||
+ bgp->evpn_info->dad_time != EVPN_DAD_DEFAULT_TIME)
+ vty_out(vty, " dup-addr-detection max-moves %u time %u\n",
+ bgp->evpn_info->dad_max_moves,
+ bgp->evpn_info->dad_time);
+
+ if (bgp->evpn_info->dad_freeze) {
+ if (bgp->evpn_info->dad_freeze_time)
+ vty_out(vty,
+ " dup-addr-detection freeze %u\n",
+ bgp->evpn_info->dad_freeze_time);
+ else
+ vty_out(vty,
+ " dup-addr-detection freeze permanent\n");
+ }
+
if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_DISABLED)
vty_out(vty, " flooding disable\n");
@@ -5013,6 +5157,9 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
+ install_element(BGP_EVPN_NODE, &dup_addr_detection_cmd);
+ install_element(BGP_EVPN_NODE, &dup_addr_detection_auto_recovery_cmd);
+ install_element(BGP_EVPN_NODE, &no_dup_addr_detection_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd);
/* test commands */
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 62f977eee..b9a874051 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -58,6 +58,7 @@
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_labelpool.h"
#include "bgpd/bgp_pbr.h"
+#include "bgpd/bgp_evpn_private.h"
/* All information about zebra. */
struct zclient *zclient = NULL;
@@ -1998,6 +1999,42 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
return zclient_send_message(zclient);
}
+int bgp_zebra_dup_addr_detection(struct bgp *bgp)
+{
+ struct stream *s;
+
+ /* Check socket. */
+ if (!zclient || zclient->sock < 0)
+ return 0;
+
+ /* Don't try to register if Zebra doesn't know of this instance. */
+ if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
+ return 0;
+
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("dup addr detect %s max_moves %u time %u freeze %s freeze_time %u",
+ bgp->evpn_info->dup_addr_detect ?
+ "enable" : "disable",
+ bgp->evpn_info->dad_max_moves,
+ bgp->evpn_info->dad_time,
+ bgp->evpn_info->dad_freeze ?
+ "enable" : "disable",
+ bgp->evpn_info->dad_freeze_time);
+
+ s = zclient->obuf;
+ stream_reset(s);
+ zclient_create_header(s, ZEBRA_DUPLICATE_ADDR_DETECTION,
+ bgp->vrf_id);
+ stream_putl(s, bgp->evpn_info->dup_addr_detect);
+ stream_putl(s, bgp->evpn_info->dad_time);
+ stream_putl(s, bgp->evpn_info->dad_max_moves);
+ stream_putl(s, bgp->evpn_info->dad_freeze);
+ stream_putl(s, bgp->evpn_info->dad_freeze_time);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zclient_send_message(zclient);
+}
+
static int rule_notify_owner(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index 2ea1fc777..e7b7d683a 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -73,6 +73,7 @@ extern int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise,
vni_t vni);
extern int bgp_zebra_advertise_gw_macip(struct bgp *, int, vni_t);
extern int bgp_zebra_advertise_all_vni(struct bgp *, int);
+extern int bgp_zebra_dup_addr_detection(struct bgp *bgp);
extern int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
enum vxlan_flood_control flood_ctrl);
diff --git a/lib/log.c b/lib/log.c
index 5cc303daf..38e526075 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -1030,6 +1030,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_REMOTE_VTEP_DEL),
DESC_ENTRY(ZEBRA_MACIP_ADD),
DESC_ENTRY(ZEBRA_MACIP_DEL),
+ DESC_ENTRY(ZEBRA_DUPLICATE_ADDR_DETECTION),
DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_ADD),
DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_DEL),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_ADD),
diff --git a/lib/zclient.h b/lib/zclient.h
index 07fe512a3..f26097e64 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -131,6 +131,7 @@ typedef enum {
ZEBRA_REMOTE_VTEP_DEL,
ZEBRA_MACIP_ADD,
ZEBRA_MACIP_DEL,
+ ZEBRA_DUPLICATE_ADDR_DETECTION,
ZEBRA_IP_PREFIX_ROUTE_ADD,
ZEBRA_IP_PREFIX_ROUTE_DEL,
ZEBRA_REMOTE_MACIP_ADD,