]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: extract local mac add code from vxlan
authorPat Ruddy <pat@voltanet.io>
Thu, 23 Jul 2020 22:04:53 +0000 (15:04 -0700)
committerPat Ruddy <pat@voltanet.io>
Wed, 12 Aug 2020 11:39:34 +0000 (12:39 +0100)
extract the local mac add code from zebra_vxlan_local_mac_add_update
and create a new generic local mac add function
zebra_evpn_add_update_local_mac

Signed-off-by: Pat Ruddy <pat@voltanet.io>
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_mac.h
zebra/zebra_vxlan.c

index a220da4553908162a93ccadeff02f43595c796f2..de0f2b80d76a584d0eefce60fbc47bab876a98bc 100644 (file)
@@ -226,8 +226,9 @@ void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac)
                zebra_evpn_mac_del(zevpn, mac);
 }
 
-void zebra_evpn_mac_get_access_info(zebra_mac_t *mac, struct interface **ifpP,
-                                   vlanid_t *vid)
+static void zebra_evpn_mac_get_access_info(zebra_mac_t *mac,
+                                          struct interface **ifpP,
+                                          vlanid_t *vid)
 {
        /* if the mac is associated with an ES we must get the access
         * info from the ES
@@ -329,10 +330,11 @@ static int zebra_evpn_dad_mac_auto_recovery_exp(struct thread *t)
        return 0;
 }
 
-void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
-                                       zebra_mac_t *mac,
-                                       struct in_addr vtep_ip, bool do_dad,
-                                       bool *is_dup_detect, bool is_local)
+static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
+                                              zebra_mac_t *mac,
+                                              struct in_addr vtep_ip,
+                                              bool do_dad, bool *is_dup_detect,
+                                              bool is_local)
 {
        zebra_neigh_t *nbr;
        struct listnode *node = NULL;
@@ -1602,8 +1604,9 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
 /* update local fowarding info. return true if a dest-ES change
  * is detected
  */
-bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
-                                         struct interface *ifp, vlanid_t vid)
+static bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
+                                                struct interface *ifp,
+                                                vlanid_t vid)
 {
        struct zebra_if *zif = ifp->info;
        bool es_change;
@@ -1877,3 +1880,240 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
        *macp = mac;
        return 0;
 }
+
+int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
+                                   struct interface *ifp,
+                                   struct ethaddr *macaddr, vlanid_t vid,
+                                   bool sticky, bool local_inactive,
+                                   bool dp_static)
+{
+       zebra_mac_t *mac;
+       char buf[ETHER_ADDR_STRLEN];
+       bool mac_sticky = false;
+       bool inform_client = false;
+       bool upd_neigh = false;
+       bool is_dup_detect = false;
+       struct in_addr vtep_ip = {.s_addr = 0};
+       bool es_change = false;
+       bool new_bgp_ready;
+       /* assume inactive if not present or if not local */
+       bool old_local_inactive = true;
+       bool old_bgp_ready = false;
+       bool inform_dataplane = false;
+       bool new_static = false;
+
+       /* Check if we need to create or update or it is a NO-OP. */
+       mac = zebra_evpn_mac_lookup(zevpn, macaddr);
+       if (!mac) {
+               if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
+                       zlog_debug(
+                               "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u%s",
+                               sticky ? "sticky " : "",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zevpn->vni,
+                               local_inactive ? " local-inactive" : "");
+
+               mac = zebra_evpn_mac_add(zevpn, macaddr);
+               if (!mac) {
+                       flog_err(
+                               EC_ZEBRA_MAC_ADD_FAILED,
+                               "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zevpn->vni);
+                       return -1;
+               }
+               SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
+               es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
+               if (sticky)
+                       SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+               inform_client = true;
+       } else {
+               if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
+                       zlog_debug(
+                               "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x",
+                               sticky ? "sticky " : "",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zevpn->vni,
+                               local_inactive ? "local-inactive " : "",
+                               mac->flags);
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
+                       struct interface *old_ifp;
+                       vlanid_t old_vid;
+                       bool old_static;
+
+                       zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid);
+                       old_bgp_ready =
+                               zebra_evpn_mac_is_ready_for_bgp(mac->flags);
+                       old_local_inactive =
+                               !!(mac->flags & ZEBRA_MAC_LOCAL_INACTIVE);
+                       old_static = zebra_evpn_mac_is_static(mac);
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+                               mac_sticky = true;
+
+                       /*
+                        * Update any changes and if changes are relevant to
+                        * BGP, note it.
+                        */
+                       if (mac_sticky == sticky && old_ifp == ifp
+                           && old_vid == vid
+                           && old_local_inactive == local_inactive
+                           && dp_static == old_static) {
+                               if (IS_ZEBRA_DEBUG_VXLAN)
+                                       zlog_debug(
+                                               "        Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, "
+                                               "entry exists and has not changed ",
+                                               sticky ? "sticky " : "",
+                                               prefix_mac2str(macaddr, buf,
+                                                              sizeof(buf)),
+                                               ifp->name, ifp->ifindex, vid,
+                                               zevpn->vni,
+                                               local_inactive
+                                                       ? " local_inactive"
+                                                       : "");
+                               return 0;
+                       }
+                       if (mac_sticky != sticky) {
+                               if (sticky)
+                                       SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+                               else
+                                       UNSET_FLAG(mac->flags,
+                                                  ZEBRA_MAC_STICKY);
+                               inform_client = true;
+                       }
+
+                       es_change = zebra_evpn_local_mac_update_fwd_info(
+                               mac, ifp, vid);
+                       /* If an es_change is detected we need to advertise
+                        * the route with a sequence that is one
+                        * greater. This is need to indicate a mac-move
+                        * to the ES peers
+                        */
+                       if (es_change) {
+                               mac->loc_seq = mac->loc_seq + 1;
+                               /* force drop the peer/sync info as it is
+                                * simply no longer relevant
+                                */
+                               if (CHECK_FLAG(mac->flags,
+                                              ZEBRA_MAC_ALL_PEER_FLAGS)) {
+                                       zebra_evpn_mac_clear_sync_info(mac);
+                                       new_static =
+                                               zebra_evpn_mac_is_static(mac);
+                                       /* if we clear peer-flags we
+                                        * also need to notify the dataplane
+                                        * to drop the static flag
+                                        */
+                                       if (old_static != new_static)
+                                               inform_dataplane = true;
+                               }
+                       }
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
+                          || CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
+                       bool do_dad = false;
+
+                       /*
+                        * MAC has either moved or was "internally" created due
+                        * to a neighbor learn and is now actually learnt. If
+                        * it was learnt as a remote sticky MAC, this is an
+                        * operator error.
+                        */
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
+                               flog_warn(
+                                       EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
+                                       "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
+                                       prefix_mac2str(macaddr, buf,
+                                                      sizeof(buf)),
+                                       inet_ntoa(mac->fwd_info.r_vtep_ip),
+                                       zevpn->vni);
+                               return 0;
+                       }
+
+                       /* If an actual move, compute MAC's seq number */
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                               mac->loc_seq =
+                                       MAX(mac->rem_seq + 1, mac->loc_seq);
+                               vtep_ip = mac->fwd_info.r_vtep_ip;
+                               /* Trigger DAD for remote MAC */
+                               do_dad = true;
+                       }
+
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+                       SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
+                       es_change = zebra_evpn_local_mac_update_fwd_info(
+                               mac, ifp, vid);
+                       if (sticky)
+                               SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+                       else
+                               UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+                       /*
+                        * We have to inform BGP of this MAC as well as process
+                        * all neighbors.
+                        */
+                       inform_client = true;
+                       upd_neigh = true;
+
+                       zebra_evpn_dup_addr_detect_for_mac(
+                               zvrf, mac, vtep_ip, do_dad, &is_dup_detect,
+                               true);
+                       if (is_dup_detect) {
+                               inform_client = false;
+                               upd_neigh = false;
+                       }
+               }
+       }
+
+       /* if the dataplane thinks the entry is sync but it is
+        * not sync in zebra we need to re-install to fixup
+        */
+       if (dp_static) {
+               new_static = zebra_evpn_mac_is_static(mac);
+               if (!new_static)
+                       inform_dataplane = true;
+       }
+
+       if (local_inactive)
+               SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
+       else
+               UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
+
+       new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
+       /* if local-activity has changed we need update bgp
+        * even if bgp already knows about the mac
+        */
+       if ((old_local_inactive != local_inactive)
+           || (new_bgp_ready != old_bgp_ready)) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
+                       zlog_debug(
+                               "local mac vni %u mac %s es %s seq %d f 0x%x%s",
+                               zevpn->vni,
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               mac->es ? mac->es->esi_str : "", mac->loc_seq,
+                               mac->flags,
+                               local_inactive ? " local-inactive" : "");
+               inform_client = true;
+       }
+
+       if (es_change) {
+               inform_client = true;
+               upd_neigh = true;
+       }
+
+       /* Inform dataplane if required. */
+       if (inform_dataplane)
+               zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
+                                              false /* force_clear_static */,
+                                              __func__);
+
+       /* Inform BGP if required. */
+       if (inform_client)
+               zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
+                                                     new_bgp_ready);
+
+       /* Process all neighbors associated with this MAC, if required. */
+       if (upd_neigh)
+               zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
+                                                            es_change);
+
+       return 0;
+}
index 8bb18396a34028a47e0e656ca38bc7da12684ba6..1ecd4aaf87ffbbfad3f0b0ab9c5d10086c36429c 100644 (file)
@@ -205,8 +205,6 @@ int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac);
 int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac,
                               bool was_static);
 void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac);
-void zebra_evpn_mac_get_access_info(zebra_mac_t *mac, struct interface **ifpP,
-                                   vlanid_t *vid);
 zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi, struct ethaddr *mac);
 zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi, struct ethaddr *macaddr);
 int zebra_evpn_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac);
@@ -214,18 +212,14 @@ int zebra_evpn_macip_send_msg_to_client(uint32_t id, struct ethaddr *macaddr,
                                        struct ipaddr *ip, uint8_t flags,
                                        uint32_t seq, int state,
                                        struct zebra_evpn_es *es, uint16_t cmd);
-void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
-                                          bool new_bgp_ready);
-void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
-                                       zebra_mac_t *mac,
-                                       struct in_addr vtep_ip, bool do_dad,
-                                       bool *is_dup_detect, bool is_local);
 void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
 void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt);
 void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt);
 void zebra_evpn_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive,
                                    bool force_clear_static,
                                    const char *caller);
+void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
+                                          bool new_bgp_ready);
 
 void zebra_evpn_mac_del_all(zebra_evpn_t *zevi, int uninstall, int upd_client,
                            uint32_t flags);
@@ -251,12 +245,11 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
                                 struct in_addr vtep_ip, uint8_t flags,
                                 uint32_t seq, esi_t *esi);
 
-// remove later
-void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
-                                          bool new_bgp_ready);
-bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
-                                         struct interface *ifp, vlanid_t vid);
-
+int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
+                                   struct interface *ifp,
+                                   struct ethaddr *macaddr, vlanid_t vid,
+                                   bool sticky, bool local_inactive,
+                                   bool dp_static);
 #ifdef __cplusplus
 }
 #endif
index 2d58c275d1cade7066592c4349e147ca0bf2b1ff..22194ee6127e9fd6bed41275ffe6002746f88f32 100644 (file)
@@ -7998,21 +7998,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
                                         bool dp_static)
 {
        zebra_evpn_t *zevpn;
-       zebra_mac_t *mac;
        struct zebra_vrf *zvrf;
        char buf[ETHER_ADDR_STRLEN];
-       bool mac_sticky = false;
-       bool inform_client = false;
-       bool upd_neigh = false;
-       bool is_dup_detect = false;
-       struct in_addr vtep_ip = {.s_addr = 0};
-       bool es_change = false;
-       bool new_bgp_ready;
-       /* assume inactive if not present or if not local */
-       bool old_local_inactive = true;
-       bool old_bgp_ready = false;
-       bool inform_dataplane = false;
-       bool new_static = false;
 
        if (ifp == NULL)
                return -1;
@@ -8047,222 +8034,9 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
                return -1;
        }
 
-       /* Check if we need to create or update or it is a NO-OP. */
-       mac = zebra_evpn_mac_lookup(zevpn, macaddr);
-       if (!mac) {
-               if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
-                       zlog_debug(
-                               "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u%s",
-                               sticky ? "sticky " : "",
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               ifp->name, ifp->ifindex, vid, zevpn->vni,
-                               local_inactive ? " local-inactive" : "");
-
-               mac = zebra_evpn_mac_add(zevpn, macaddr);
-               if (!mac) {
-                       flog_err(
-                               EC_ZEBRA_MAC_ADD_FAILED,
-                               "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               ifp->name, ifp->ifindex, vid, zevpn->vni);
-                       return -1;
-               }
-               SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
-               es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
-               if (sticky)
-                       SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-               inform_client = true;
-       } else {
-               if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
-                       zlog_debug(
-                               "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x",
-                               sticky ? "sticky " : "",
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               ifp->name, ifp->ifindex, vid, zevpn->vni,
-                               local_inactive ? "local-inactive " : "",
-                               mac->flags);
-
-               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
-                       struct interface *old_ifp;
-                       vlanid_t old_vid;
-                       bool old_static;
-
-                       zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid);
-                       old_bgp_ready =
-                               zebra_evpn_mac_is_ready_for_bgp(mac->flags);
-                       old_local_inactive = !!(mac->flags &
-                                       ZEBRA_MAC_LOCAL_INACTIVE);
-                       old_static = zebra_evpn_mac_is_static(mac);
-                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
-                               mac_sticky = true;
-
-                       /*
-                        * Update any changes and if changes are relevant to
-                        * BGP, note it.
-                        */
-                       if (mac_sticky == sticky
-                           && old_ifp == ifp
-                           && old_vid == vid
-                               && old_local_inactive == local_inactive
-                               && dp_static == old_static) {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug(
-                                               "        Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, entry exists and has not changed ",
-                                               sticky ? "sticky " : "",
-                                               prefix_mac2str(macaddr, buf,
-                                                              sizeof(buf)),
-                                               ifp->name, ifp->ifindex, vid,
-                                               zevpn->vni,
-                                               local_inactive ?
-                                               " local_inactive" : "");
-                               return 0;
-                       }
-                       if (mac_sticky != sticky) {
-                               if (sticky)
-                                       SET_FLAG(mac->flags,
-                                                ZEBRA_MAC_STICKY);
-                               else
-                                       UNSET_FLAG(mac->flags,
-                                                  ZEBRA_MAC_STICKY);
-                               inform_client = true;
-                       }
-
-                       es_change = zebra_evpn_local_mac_update_fwd_info(
-                               mac, ifp, vid);
-                       /* If an es_change is detected we need to advertise
-                        * the route with a sequence that is one
-                        * greater. This is need to indicate a mac-move
-                        * to the ES peers
-                        */
-                       if (es_change) {
-                               mac->loc_seq = mac->loc_seq + 1;
-                               /* force drop the peer/sync info as it is
-                                * simply no longer relevant
-                                */
-                               if (CHECK_FLAG(mac->flags,
-                                       ZEBRA_MAC_ALL_PEER_FLAGS)) {
-                                       zebra_evpn_mac_clear_sync_info(mac);
-                                       new_static =
-                                               zebra_evpn_mac_is_static(mac);
-                                       /* if we clear peer-flags we
-                                        * also need to notify the dataplane
-                                        * to drop the static flag
-                                        */
-                                       if (old_static != new_static)
-                                               inform_dataplane = true;
-                               }
-                       }
-               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
-                          CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
-                       bool do_dad = false;
-
-                       /*
-                        * MAC has either moved or was "internally" created due
-                        * to a neighbor learn and is now actually learnt. If
-                        * it was learnt as a remote sticky MAC, this is an
-                        * operator error.
-                        */
-                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
-                               flog_warn(
-                                       EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
-                                       "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
-                                       prefix_mac2str(macaddr, buf,
-                                                      sizeof(buf)),
-                                       inet_ntoa(mac->fwd_info.r_vtep_ip),
-                                       zevpn->vni);
-                               return 0;
-                       }
-
-                       /* If an actual move, compute MAC's seq number */
-                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
-                               mac->loc_seq = MAX(mac->rem_seq + 1,
-                                                  mac->loc_seq);
-                               vtep_ip = mac->fwd_info.r_vtep_ip;
-                               /* Trigger DAD for remote MAC */
-                               do_dad = true;
-                       }
-
-                       UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
-                       UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
-                       SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
-                       es_change = zebra_evpn_local_mac_update_fwd_info(
-                               mac, ifp, vid);
-                       if (sticky)
-                               SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-                       else
-                               UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-                       /*
-                        * We have to inform BGP of this MAC as well as process
-                        * all neighbors.
-                        */
-                       inform_client = true;
-                       upd_neigh = true;
-
-                       zebra_evpn_dup_addr_detect_for_mac(
-                               zvrf, mac, vtep_ip, do_dad, &is_dup_detect,
-                               true);
-                       if (is_dup_detect) {
-                               inform_client = false;
-                               upd_neigh = false;
-                       }
-               }
-       }
-
-       /* if the dataplane thinks the entry is sync but it is
-        * not sync in zebra we need to re-install to fixup
-        */
-       if (dp_static) {
-               new_static = zebra_evpn_mac_is_static(mac);
-               if (!new_static)
-                       inform_dataplane = true;
-       }
-
-       if (local_inactive)
-               SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
-       else
-               UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
-
-       new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
-       /* if local-activity has changed we need update bgp
-        * even if bgp already knows about the mac
-        */
-       if ((old_local_inactive != local_inactive) ||
-                       (new_bgp_ready != old_bgp_ready)) {
-               if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
-                       zlog_debug("local mac vni %u mac %s es %s seq %d f 0x%x%s",
-                                       zevpn->vni,
-                                       prefix_mac2str(macaddr,
-                                               buf, sizeof(buf)),
-                                       mac->es ? mac->es->esi_str : "",
-                                       mac->loc_seq,
-                                       mac->flags,
-                                       local_inactive ?
-                                       " local-inactive" : "");
-               inform_client = true;
-       }
-
-       if (es_change) {
-               inform_client = true;
-               upd_neigh = true;
-       }
-
-       /* Inform dataplane if required. */
-       if (inform_dataplane)
-               zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
-                                              false /* force_clear_static */,
-                                              __func__);
-
-       /* Inform BGP if required. */
-       if (inform_client)
-               zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
-                                                     new_bgp_ready);
-
-       /* Process all neighbors associated with this MAC, if required. */
-       if (upd_neigh)
-               zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
-                                                            es_change);
-
-       return 0;
+       return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid,
+                                              sticky, local_inactive,
+                                              dp_static);
 }
 
 /*