From: Anuradha Karuppiah Date: Mon, 11 May 2020 01:02:37 +0000 (-0700) Subject: zebra: Keep DAD disabled if EVPN MH is turned on X-Git-Tag: base_7.6~187^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=b2ee2b71f4864c691e7b022e06e01b521745bc85;p=matthieu%2Ffrr.git zebra: Keep DAD disabled if EVPN MH is turned on DAD is not supported currently with EVPN-MH so we turn it off internally when the first ES config is detected. PS: Note that when all local ESs are deleted DAD will stay off and will need to be cleared via a daemon restart. Signed-off-by: Anuradha Karuppiah --- diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 4a2d8db422..29efa1700e 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -343,7 +343,7 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, 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, diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 692dfca5d7..93b7823d57 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -1660,6 +1660,36 @@ void zebra_evpn_es_local_br_port_update(struct zebra_if *zif) 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) { @@ -1670,6 +1700,8 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, 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); diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 09af26a3a3..c232e3b8f2 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -164,6 +164,12 @@ struct zebra_evpn_access_bd { /* 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 */ @@ -228,6 +234,12 @@ static inline bool zebra_evpn_mh_is_fdb_nh(uint32_t id) (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); diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index e4f38008ac..6d72bc570e 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -984,7 +984,8 @@ void zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn, || 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( @@ -1106,7 +1107,7 @@ static int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf, 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 @@ -1203,7 +1204,7 @@ zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr, 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 @@ -1456,7 +1457,7 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, * 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)); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 4b3b142d40..64351b8072 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -118,6 +118,11 @@ static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, 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) @@ -3417,7 +3422,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) 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 @@ -3436,7 +3441,8 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) 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) { @@ -3505,6 +3511,7 @@ void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS) 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); @@ -3513,13 +3520,16 @@ void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS) 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; @@ -3529,9 +3539,8 @@ void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS) 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); diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index 9a88d98b81..4ec55542a7 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -258,5 +258,6 @@ typedef struct zebra_vxlan_sg_ { 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 */