char buf1[INET6_ADDRSTRLEN];
bool reset_params = false;
- if (!(zvrf->dup_addr_detect && do_dad))
+ if (!(zebra_evpn_do_dup_addr_detect(zvrf) && do_dad))
return;
/* MAC is detected as duplicate,
zebra_evpn_es_br_port_dplane_update(es, __func__);
}
+/* On config of first local-ES turn off DAD */
+static void zebra_evpn_mh_dup_addr_detect_off(void)
+{
+ struct zebra_vrf *zvrf;
+ bool old_detect;
+ bool new_detect;
+
+ if (zmh_info->flags & ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF)
+ return;
+
+ zvrf = zebra_vrf_get_evpn();
+ if (!zvrf) {
+ zmh_info->flags |= ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF;
+ return;
+ }
+
+ old_detect = zebra_evpn_do_dup_addr_detect(zvrf);
+ zmh_info->flags |= ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF;
+ new_detect = zebra_evpn_do_dup_addr_detect(zvrf);
+
+ if (old_detect && !new_detect) {
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+ zlog_debug(
+ "evpn-mh config caused DAD addr detect chg from %s to %s",
+ old_detect ? "on" : "off",
+ new_detect ? "on" : "off");
+ zebra_vxlan_clear_dup_detect_vni_all(zvrf);
+ }
+}
+
static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
struct zebra_if *zif)
{
zlog_debug("local es %s add; nhg 0x%x if %s",
es->esi_str, es->nhg_id, zif->ifp->name);
+ zebra_evpn_mh_dup_addr_detect_off();
+
es->flags |= ZEBRA_EVPNES_LOCAL;
listnode_init(&es->local_es_listnode, es);
listnode_add(zmh_info->local_es_list, &es->local_es_listnode);
/* multihoming information stored in zrouter */
#define zmh_info (zrouter.mh_info)
struct zebra_evpn_mh_info {
+ uint32_t flags;
+/* DAD support for EVPN-MH is yet to be added. So on detection of
+ * first local ES, DAD is turned off
+ */
+#define ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF (1 << 1)
+
/* RB tree of Ethernet segments (used for EVPN-MH) */
struct zebra_es_rb_head es_rb_tree;
/* List of local ESs */
(id & EVPN_NH_ID_TYPE_BIT));
}
+static inline bool zebra_evpn_mh_do_dup_addr_detect(void)
+{
+ return !(zmh_info->flags & ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF);
+}
+
+
/*****************************************************************************/
extern esi_t *zero_esi;
extern void zebra_evpn_mh_init(void);
|| es_change) {
ZEBRA_NEIGH_SET_ACTIVE(n);
n->loc_seq = zmac->loc_seq;
- if (!(zvrf->dup_addr_detect && zvrf->dad_freeze
+ if (!(zebra_evpn_do_dup_addr_detect(zvrf)
+ && zvrf->dad_freeze
&& !!CHECK_FLAG(n->flags,
ZEBRA_NEIGH_DUPLICATE)))
zebra_evpn_neigh_send_add_to_client(
bool is_old_mac_dup = false;
bool is_new_mac_dup = false;
- if (!zvrf->dup_addr_detect)
+ if (!zebra_evpn_do_dup_addr_detect(zvrf))
return 0;
/* Check old or new MAC is detected as duplicate
* mark this neigh as duplicate
char buf1[INET6_ADDRSTRLEN];
bool reset_params = false;
- if (!zvrf->dup_addr_detect)
+ if (!zebra_evpn_do_dup_addr_detect(zvrf))
return;
/* IP is detected as duplicate or inherit dup
* is enabled, do not send update to client.
*/
is_neigh_freezed =
- (zvrf->dup_addr_detect
+ (zebra_evpn_do_dup_addr_detect(zvrf)
&& zvrf->dad_freeze
&& CHECK_FLAG(n->flags,
ZEBRA_NEIGH_DUPLICATE));
struct in_addr mcast_grp);
static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg);
+bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf)
+{
+ return zvrf->dup_addr_detect && zebra_evpn_mh_do_dup_addr_detect();
+}
+
/* Private functions */
static int host_rb_entry_compare(const struct host_rb_entry *hle1,
const struct host_rb_entry *hle2)
json_object_int_add(json, "numVnis", num_vnis);
json_object_int_add(json, "numL2Vnis", num_l2vnis);
json_object_int_add(json, "numL3Vnis", num_l3vnis);
- if (zvrf->dup_addr_detect)
+ if (zebra_evpn_do_dup_addr_detect(zvrf))
json_object_boolean_true_add(json,
"isDuplicateAddrDetection");
else
vty_out(vty, "Advertise svi mac-ip: %s\n",
zvrf->advertise_svi_macip ? "Yes" : "No");
vty_out(vty, "Duplicate address detection: %s\n",
- zvrf->dup_addr_detect ? "Enable" : "Disable");
+ zebra_evpn_do_dup_addr_detect(zvrf) ? "Enable"
+ : "Disable");
vty_out(vty, " Detection max-moves %u, time %d\n",
zvrf->dad_max_moves, zvrf->dad_time);
if (zvrf->dad_freeze) {
uint32_t freeze_time = 0;
bool dup_addr_detect = false;
bool freeze = false;
+ bool old_addr_detect;
s = msg;
STREAM_GETL(s, dup_addr_detect);
STREAM_GETL(s, freeze);
STREAM_GETL(s, freeze_time);
+ old_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
+ zvrf->dup_addr_detect = dup_addr_detect;
+ dup_addr_detect = zebra_evpn_do_dup_addr_detect(zvrf);
+
/* DAD previous state was enabled, and new state is disable,
* clear all duplicate detected addresses.
*/
- if (zvrf->dup_addr_detect && !dup_addr_detect)
+ if (old_addr_detect && !dup_addr_detect)
zebra_vxlan_clear_dup_detect_vni_all(zvrf);
- zvrf->dup_addr_detect = dup_addr_detect;
zvrf->dad_time = time;
zvrf->dad_max_moves = max_moves;
zvrf->dad_freeze = freeze;
zlog_debug(
"VRF %s duplicate detect %s max_moves %u timeout %u freeze %s freeze_time %u",
vrf_id_to_name(zvrf->vrf->vrf_id),
- zvrf->dup_addr_detect ? "enable" : "disable",
- zvrf->dad_max_moves,
- zvrf->dad_time,
+ dup_addr_detect ? "enable" : "disable",
+ zvrf->dad_max_moves, zvrf->dad_time,
zvrf->dad_freeze ? "enable" : "disable",
zvrf->dad_freeze_time);
extern zebra_evpn_t *zevpn_lookup(vni_t vni);
extern void zebra_vxlan_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive,
bool force_clear_static, const char *caller);
+extern bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf);
#endif /* _ZEBRA_VXLAN_PRIVATE_H */