diff options
-rw-r--r-- | bgpd/bgp_evpn.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_evpn_vty.c | 147 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 37 | ||||
-rw-r--r-- | bgpd/bgp_zebra.h | 1 | ||||
-rw-r--r-- | lib/log.c | 1 | ||||
-rw-r--r-- | lib/zclient.h | 1 |
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); @@ -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, |