Merge pull request #3176 from chiragshah6/evpn_dev

zebra: duplicate address detection and dampening
This commit is contained in:
Russ White 2018-11-25 22:17:33 -05:00 committed by GitHub
commit 19e5a46591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1794 additions and 25 deletions

View File

@ -5802,6 +5802,21 @@ void bgp_evpn_init(struct bgp *bgp)
bgp->vrf_export_rtl->del = evpn_xxport_delete_ecomm;
bgp->l2vnis = list_new();
bgp->l2vnis->cmp = vni_list_cmp;
/* By default Duplicate Address Dection is enabled.
* Max-moves (N) 5, detection time (M) 180
* default action is warning-only
* freeze action permanently freezes address,
* and freeze time (auto-recovery) is disabled.
*/
if (bgp->evpn_info) {
bgp->evpn_info->dup_addr_detect = true;
bgp->evpn_info->dad_time = EVPN_DAD_DEFAULT_TIME;
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. */
bgp->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;

View File

@ -161,6 +161,24 @@ struct vrf_irt_node {
#define RT_TYPE_EXPORT 2
#define RT_TYPE_BOTH 3
#define EVPN_DAD_DEFAULT_TIME 180 /* secs */
#define EVPN_DAD_DEFAULT_MAX_MOVES 5 /* default from RFC 7432 */
#define EVPN_DAD_DEFAULT_AUTO_RECOVERY_TIME 1800 /* secs */
struct bgp_evpn_info {
/* enable disable dup detect */
bool dup_addr_detect;
/* Detection time(M) */
int dad_time;
/* Detection max moves(N) */
uint32_t dad_max_moves;
/* Permanent freeze */
bool dad_freeze;
/* Recovery time */
uint32_t dad_freeze_time;
};
static inline int is_vrf_rd_configured(struct bgp *bgp_vrf)
{
return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD));

View File

@ -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 moves 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 moves 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 */

View File

@ -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;
@ -1999,6 +2000,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)
{

View File

@ -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);

View File

@ -86,8 +86,10 @@
#include "bgpd/bgp_labelpool.h"
#include "bgpd/bgp_pbr.h"
#include "bgpd/bgp_addpath.h"
#include "bgpd/bgp_evpn_private.h"
DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
DEFINE_MTYPE_STATIC(BGPD, BGP_EVPN_INFO, "BGP EVPN instance information");
DEFINE_QOBJ_TYPE(bgp_master)
DEFINE_QOBJ_TYPE(bgp)
DEFINE_QOBJ_TYPE(peer)
@ -2982,6 +2984,9 @@ static struct bgp *bgp_create(as_t *as, const char *name,
/* assign a unique rd id for auto derivation of vrf's RD */
bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO,
sizeof(struct bgp_evpn_info));
bgp_evpn_init(bgp);
bgp_pbr_init(bgp);
return bgp;
@ -3373,6 +3378,7 @@ void bgp_free(struct bgp *bgp)
bgp_evpn_cleanup(bgp);
bgp_pbr_cleanup(bgp);
XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
vpn_policy_direction_t dir;

View File

@ -482,6 +482,8 @@ struct bgp {
/* EVPN enable - advertise local VNIs and their MACs etc. */
int advertise_all_vni;
struct bgp_evpn_info *evpn_info;
/* EVPN - use RFC 8365 to auto-derive RT */
int advertise_autort_rfc8365;

View File

@ -1034,6 +1034,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_DEL),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_ADD),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_DEL),
DESC_ENTRY(ZEBRA_DUPLICATE_ADDR_DETECTION),
DESC_ENTRY(ZEBRA_PW_ADD),
DESC_ENTRY(ZEBRA_PW_DELETE),
DESC_ENTRY(ZEBRA_PW_SET),

View File

@ -80,4 +80,15 @@ static inline int64_t monotime_until(const struct timeval *ref,
return (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec;
}
static inline char *time_to_string(time_t ts)
{
struct timeval tv;
time_t tbuf;
monotime(&tv);
tbuf = time(NULL) - (tv.tv_sec - ts);
return ctime(&tbuf);
}
#endif /* _FRR_MONOTIME_H */

View File

@ -135,6 +135,7 @@ typedef enum {
ZEBRA_IP_PREFIX_ROUTE_DEL,
ZEBRA_REMOTE_MACIP_ADD,
ZEBRA_REMOTE_MACIP_DEL,
ZEBRA_DUPLICATE_ADDR_DETECTION,
ZEBRA_PW_ADD,
ZEBRA_PW_DELETE,
ZEBRA_PW_SET,

View File

@ -2443,6 +2443,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
[ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
[ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
[ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
[ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
[ZEBRA_PW_ADD] = zread_pseudowire,
[ZEBRA_PW_DELETE] = zread_pseudowire,

View File

@ -694,6 +694,33 @@ static struct log_ref ferr_zebra_err[] = {
.suggestion =
"Do not use v6 sourcedest routes, or upgrade your kernel.",
},
{
.code = EC_ZEBRA_DUP_MAC_DETECTED,
.title =
"EVPN MAC is detected duplicate",
.description =
"Zebra has hit duplicate address detection threshold which means host MAC is moving.",
.suggestion =
"Check network topology to detect duplicate host MAC for correctness.",
},
{
.code = EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
.title =
"EVPN IP is detected duplicate by MAC",
.description =
"Zebra has hit duplicate address detection threshold which means MAC-IP pair is moving.",
.suggestion =
"Check network topology to detect duplicate host MAC for correctness.",
},
{
.code = EC_ZEBRA_DUP_IP_DETECTED,
.title =
"EVPN IP is detected duplicate",
.description =
"Zebra has hit duplicate address detection threshold which means host IP is moving.",
.suggestion =
"Check network topology to detect duplicate host IP for correctness.",
},
{
.code = END_FERR,
}

View File

@ -117,6 +117,9 @@ enum zebra_log_refs {
EC_ZEBRA_MAX_LABELS_PUSH,
EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
EC_ZEBRA_UNSUPPORTED_V6_SRCDEST,
EC_ZEBRA_DUP_MAC_DETECTED,
EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
EC_ZEBRA_DUP_IP_DETECTED,
};
void zebra_error_init(void);

View File

@ -125,6 +125,13 @@ struct zebra_vrf {
/* l3-vni info */
vni_t l3vni;
bool dup_addr_detect;
int dad_time;
uint32_t dad_max_moves;
bool dad_freeze;
uint32_t dad_freeze_time;
/*
* Flooding mechanism for BUM packets for VxLAN-EVPN.
*/

View File

@ -1970,7 +1970,7 @@ DEFUN (show_evpn_mac_vni_all,
bool uj = use_json(argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@ -2059,6 +2059,90 @@ DEFUN (show_evpn_mac_vni_vtep,
return CMD_SUCCESS;
}
DEFPY (show_evpn_mac_vni_all_dad,
show_evpn_mac_vni_all_dad_cmd,
"show evpn mac vni all duplicate [json]",
SHOW_STR
"EVPN\n"
"MAC addresses\n"
"VxLAN Network Identifier\n"
"All VNIs\n"
"Duplicate address list\n"
JSON_STR)
{
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
return CMD_SUCCESS;
}
DEFPY (show_evpn_mac_vni_dad,
show_evpn_mac_vni_dad_cmd,
"show evpn mac vni " CMD_VNI_RANGE " duplicate" "[json]",
SHOW_STR
"EVPN\n"
"MAC addresses\n"
"VxLAN Network Identifier\n"
"VNI number\n"
"Duplicate address list\n"
JSON_STR)
{
struct zebra_vrf *zvrf;
vni_t vni;
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
DEFPY (show_evpn_neigh_vni_dad,
show_evpn_neigh_vni_dad_cmd,
"show evpn arp-cache vni " CMD_VNI_RANGE "duplicate" "[json]",
SHOW_STR
"EVPN\n"
"ARP and ND cache\n"
"VxLAN Network Identifier\n"
"VNI number\n"
"Duplicate address list\n"
JSON_STR)
{
struct zebra_vrf *zvrf;
vni_t vni;
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
DEFPY (show_evpn_neigh_vni_all_dad,
show_evpn_neigh_vni_all_dad_cmd,
"show evpn arp-cache vni all duplicate [json]",
SHOW_STR
"EVPN\n"
"ARP and ND cache\n"
"VxLAN Network Identifier\n"
"All VNIs\n"
"Duplicate address list\n"
JSON_STR)
{
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
return CMD_SUCCESS;
}
DEFUN (show_evpn_neigh_vni,
show_evpn_neigh_vni_cmd,
"show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
@ -2093,7 +2177,7 @@ DEFUN (show_evpn_neigh_vni_all,
bool uj = use_json(argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@ -2193,6 +2277,55 @@ DEFUN (show_pbr_iptable,
return CMD_SUCCESS;
}
DEFPY (clear_evpn_dup_addr,
clear_evpn_dup_addr_cmd,
"clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni_val [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>",
CLEAR_STR
"EVPN\n"
"Duplicate address \n"
"VxLAN Network Identifier\n"
"VNI number\n"
"All VNIs\n"
"MAC\n"
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
"IP\n"
"IPv4 address\n"
"IPv6 address\n")
{
struct zebra_vrf *zvrf;
vni_t vni = 0;
struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
struct ethaddr mac_addr;
zvrf = vrf_info_lookup(VRF_DEFAULT);
if (vni_val) {
vni = strtoul(vni_val, NULL, 10);
if (mac_val) {
prefix_str2mac(mac_val, &mac_addr);
zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf, vni,
&mac_addr);
} else if (ip) {
if (sockunion_family(ip) == AF_INET) {
host_ip.ipa_type = IPADDR_V4;
host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
} else {
host_ip.ipa_type = IPADDR_V6;
memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
sizeof(struct in6_addr));
}
zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf, vni,
&host_ip);
} else
zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
} else {
zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
}
return CMD_SUCCESS;
}
/* Static ip route configuration write function. */
static int zebra_ip_config(struct vty *vty)
{
@ -2755,10 +2888,15 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
install_element(VIEW_NODE, &show_pbr_ipset_cmd);
install_element(VIEW_NODE, &show_pbr_iptable_cmd);

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,7 @@ 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);
extern void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS);
extern int is_l3vni_for_prefix_routes_only(vni_t vni);
extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);
@ -87,6 +88,7 @@ extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
vni_t vni, bool use_json);
extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
struct zebra_vrf *zvrf,
bool print_dup,
bool use_json);
extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
struct zebra_vrf *zvrf,
@ -100,10 +102,14 @@ extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
struct zebra_vrf *zvrf, vni_t vni,
struct in_addr vtep_ip,
bool use_json);
extern void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
struct zebra_vrf *zvrf, vni_t vni,
bool use_json);
extern void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
vni_t vni, bool use_json);
extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty,
struct zebra_vrf *zvrf,
bool print_dup,
bool use_json);
extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
struct zebra_vrf *zvrf,
@ -113,6 +119,9 @@ extern void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty,
struct zebra_vrf *zvrf, vni_t vni,
struct in_addr vtep_ip,
bool use_json);
extern void zebra_vxlan_print_neigh_vni_dad(struct vty *vty,
struct zebra_vrf *zvrf, vni_t vni,
bool use_json);
extern void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf,
vni_t vni, bool use_json);
extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
@ -172,5 +181,17 @@ extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
struct ipaddr *vtep_ip,
struct prefix *host_prefix);
extern void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni,
struct ethaddr *macaddr);
extern void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni, struct ipaddr *ip);
extern void zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
struct zebra_vrf *zvrf);
extern void zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni);
#endif /* _ZEBRA_VXLAN_H */

View File

@ -249,6 +249,10 @@ struct zebra_mac_t_ {
#define ZEBRA_MAC_DEF_GW 0x20
/* remote VTEP advertised MAC as default GW */
#define ZEBRA_MAC_REMOTE_DEF_GW 0x40
#define ZEBRA_MAC_DUPLICATE 0x80
/* back pointer to zvni */
zebra_vni_t *zvni;
/* Local or remote info. */
union {
@ -269,6 +273,15 @@ struct zebra_mac_t_ {
/* list of hosts pointing to this remote RMAC */
struct host_rb_tree_entry host_rb;
/* Duplicate mac detection */
uint32_t dad_count;
struct thread *dad_mac_auto_recovery_timer;
struct timeval detect_start_time;
time_t dad_dup_detect_time;
};
/*
@ -292,6 +305,7 @@ struct mac_walk_ctx {
struct vty *vty; /* Used by VTY handlers */
uint32_t count; /* Used by VTY handlers */
struct json_object *json; /* Used for JSON Output */
bool print_dup; /* Used to print dup addr list */
};
struct rmac_walk_ctx {
@ -330,12 +344,15 @@ struct zebra_neigh_t_ {
/* Underlying interface. */
ifindex_t ifindex;
zebra_vni_t *zvni;
uint32_t flags;
#define ZEBRA_NEIGH_LOCAL 0x01
#define ZEBRA_NEIGH_REMOTE 0x02
#define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
#define ZEBRA_NEIGH_DEF_GW 0x08
#define ZEBRA_NEIGH_ROUTER_FLAG 0x10
#define ZEBRA_NEIGH_DUPLICATE 0x20
enum zebra_neigh_state state;
@ -354,6 +371,15 @@ struct zebra_neigh_t_ {
/* list of hosts pointing to this remote NH entry */
struct host_rb_tree_entry host_rb;
/* Duplicate ip detection */
uint32_t dad_count;
struct thread *dad_ip_auto_recovery_timer;
struct timeval detect_start_time;
time_t dad_dup_detect_time;
};
/*