]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Keep DAD disabled if EVPN MH is turned on
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Mon, 11 May 2020 01:02:37 +0000 (18:02 -0700)
committerAnuradha Karuppiah <anuradhak@nvidia.com>
Tue, 24 Nov 2020 18:20:32 +0000 (10:20 -0800)
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 <anuradhak@cumulusnetworks.com>
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_mh.c
zebra/zebra_evpn_mh.h
zebra/zebra_evpn_neigh.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan_private.h

index 4a2d8db42237a5632b10e7f9dc74747bbf090d5e..29efa1700e41bcfe80be61b124bb3a15cf5b3c1a 100644 (file)
@@ -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,
index 692dfca5d7c292a7adbf382e8dded8d21c07dad8..93b7823d5717554f19bba608df8625e9afe66c08 100644 (file)
@@ -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);
index 09af26a3a3d437f82420f238c52172c08db074a8..c232e3b8f251302268f95f576b690d68e6daf170 100644 (file)
@@ -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);
index e4f38008ac8e135411a22bea5491a0389c687abb..6d72bc570e164ec028aabf04b3efbd3bf12d9cad 100644 (file)
@@ -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));
index 4b3b142d4024bb804cee1a903edff68b61343310..64351b8072e8f0a41473224c13bb4312410144c4 100644 (file)
@@ -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);
 
index 9a88d98b81817e9943912a9827a980e7babfb4fd..4ec55542a7255ca0a2fd9c0b8e8edf2cc3fceb7a 100644 (file)
@@ -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 */