]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: extract neigbor processing from remote_macip_add
authorPat Ruddy <pat@voltanet.io>
Fri, 24 Apr 2020 12:48:31 +0000 (13:48 +0100)
committerPat Ruddy <pat@voltanet.io>
Wed, 12 Aug 2020 11:39:34 +0000 (12:39 +0100)
extract the neighbor part of process_remote_macip_add into a new
function process_neigh_remote_macip_add in zebra_evpn_neigh.c.

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

index 98ef4a28f2cf7854a32abec4894d780040db3ba2..858f0b99f6117a477caf822c37820c67fed1fdec 100644 (file)
@@ -1081,7 +1081,8 @@ static int zebra_evpn_neigh_probe(zebra_evpn_t *zevpn, zebra_neigh_t *n)
        return 0;
 }
 
-void zebra_evpn_probe_neigh_on_mac_add(zebra_evpn_t *zevpn, zebra_mac_t *zmac)
+static void zebra_evpn_probe_neigh_on_mac_add(zebra_evpn_t *zevpn,
+                                             zebra_mac_t *zmac)
 {
        zebra_neigh_t *nbr = NULL;
        struct listnode *node = NULL;
@@ -1119,10 +1120,10 @@ static inline void zebra_evpn_local_neigh_update_log(
  * MAC binding changes, ensure to inherit duplicate flag
  * from MAC.
  */
-int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
-                                      zebra_mac_t *old_zmac,
-                                      zebra_mac_t *new_zmac,
-                                      zebra_neigh_t *nbr)
+static int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
+                                             zebra_mac_t *old_zmac,
+                                             zebra_mac_t *new_zmac,
+                                             zebra_neigh_t *nbr)
 {
        bool is_old_mac_dup = false;
        bool is_new_mac_dup = false;
@@ -1213,10 +1214,10 @@ static int zebra_evpn_dad_ip_auto_recovery_exp(struct thread *t)
        return 0;
 }
 
-void zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
-                                         zebra_neigh_t *nbr,
-                                         struct in_addr vtep_ip, bool do_dad,
-                                         bool *is_dup_detect, bool is_local)
+static void
+zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr,
+                                    struct in_addr vtep_ip, bool do_dad,
+                                    bool *is_dup_detect, bool is_local)
 {
 
        struct timeval elapsed = {0, 0};
@@ -2121,3 +2122,166 @@ void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
        if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
                zebra_evpn_print_neigh_hash_detail(bucket, ctxt);
 }
+
+void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
+                                   struct ipaddr *ipaddr, zebra_mac_t *mac,
+                                   struct in_addr vtep_ip, uint8_t flags,
+                                   uint32_t seq)
+{
+       zebra_neigh_t *n;
+       int update_neigh = 0;
+       uint32_t tmp_seq;
+       char buf[ETHER_ADDR_STRLEN];
+       char buf1[INET6_ADDRSTRLEN];
+       zebra_mac_t *old_mac = NULL;
+       bool old_static = false;
+       bool do_dad = false;
+       bool is_dup_detect = false;
+       bool is_router;
+
+       is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+
+       /* Check if the remote neighbor itself is unknown or has a
+        * change. If so, create or update and then install the entry.
+        */
+       n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
+       if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
+           || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
+           || (memcmp(&n->emac, &mac->macaddr, sizeof(struct ethaddr)) != 0)
+           || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) || seq != n->rem_seq)
+               update_neigh = 1;
+
+       if (update_neigh) {
+               if (!n) {
+                       n = zebra_evpn_neigh_add(zevpn, ipaddr, &mac->macaddr,
+                                                mac, 0);
+                       if (!n) {
+                               zlog_warn(
+                                       "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
+                                       ipaddr2str(ipaddr, buf1, sizeof(buf1)),
+                                       prefix_mac2str(&mac->macaddr, buf,
+                                                      sizeof(buf)),
+                                       zevpn->vni, inet_ntoa(vtep_ip));
+                               return;
+                       }
+
+               } else {
+                       const char *n_type;
+
+                       /* When host moves but changes its (MAC,IP)
+                        * binding, BGP may install a MACIP entry that
+                        * corresponds to "older" location of the host
+                        * in transient situations (because {IP1,M1}
+                        * is a different route from {IP1,M2}). Check
+                        * the sequence number and ignore this update
+                        * if appropriate.
+                        */
+                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
+                               tmp_seq = n->loc_seq;
+                               n_type = "local";
+                       } else {
+                               tmp_seq = n->rem_seq;
+                               n_type = "remote";
+                       }
+                       if (seq < tmp_seq) {
+                               if (IS_ZEBRA_DEBUG_VXLAN)
+                                       zlog_debug(
+                                               "Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
+                                               zevpn->vni,
+                                               prefix_mac2str(&mac->macaddr,
+                                                              buf,
+                                                              sizeof(buf)),
+                                               " IP ",
+                                               ipaddr2str(ipaddr, buf1,
+                                                          sizeof(buf1)),
+                                               n_type, tmp_seq);
+                               return;
+                       }
+                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
+                               old_static = zebra_evpn_neigh_is_static(n);
+                               if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
+                                       zlog_debug(
+                                               "sync->remote neigh vni %u ip %s mac %s seq %d f0x%x",
+                                               n->zevpn->vni,
+                                               ipaddr2str(&n->ip, buf1,
+                                                          sizeof(buf1)),
+                                               prefix_mac2str(&n->emac, buf,
+                                                              sizeof(buf)),
+                                               seq, n->flags);
+                               zebra_evpn_neigh_clear_sync_info(n);
+                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
+                                       zebra_evpn_mac_send_del_to_client(
+                                               zevpn->vni, &mac->macaddr,
+                                               mac->flags, false /*force*/);
+                       }
+                       if (memcmp(&n->emac, &mac->macaddr,
+                                  sizeof(struct ethaddr))
+                           != 0) {
+                               /* update neigh list for macs */
+                               old_mac =
+                                       zebra_evpn_mac_lookup(zevpn, &n->emac);
+                               if (old_mac) {
+                                       listnode_delete(old_mac->neigh_list, n);
+                                       n->mac = NULL;
+                                       zebra_evpn_deref_ip2mac(zevpn, old_mac);
+                               }
+                               n->mac = mac;
+                               listnode_add_sort(mac->neigh_list, n);
+                               memcpy(&n->emac, &mac->macaddr, ETH_ALEN);
+
+                               /* Check Neigh's curent state is local
+                                * (this is the case where neigh/host has  moved
+                                * from L->R) and check previous detction
+                                * started via local learning.
+                                *
+                                * RFC-7432: A PE/VTEP that detects a MAC
+                                * mobilit event via local learning starts
+                                * an M-second timer.
+                                * VTEP-IP or seq. change along is not
+                                * considered for dup. detection.
+                                *
+                                * Mobilty event scenario-B IP-MAC binding
+                                * changed.
+                                */
+                               if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
+                                   && n->dad_count)
+                                       do_dad = true;
+                       }
+               }
+
+               /* Set "remote" forwarding info. */
+               UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
+               n->r_vtep_ip = vtep_ip;
+               SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+
+               /* Set router flag (R-bit) to this Neighbor entry */
+               if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
+                       SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+               else
+                       UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
+               /* Check old or new MAC detected as duplicate,
+                * inherit duplicate flag to this neigh.
+                */
+               if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_mac, mac, n)) {
+                       flog_warn(
+                               EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
+                               "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
+                               zevpn->vni,
+                               prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
+                               ipaddr2str(&n->ip, buf1, sizeof(buf1)));
+               }
+
+               /* Check duplicate address detection for IP */
+               zebra_evpn_dup_addr_detect_for_neigh(
+                       zvrf, n, n->r_vtep_ip, do_dad, &is_dup_detect, false);
+               /* Install the entry. */
+               if (!is_dup_detect)
+                       zebra_evpn_rem_neigh_install(zevpn, n, old_static);
+       }
+
+       zebra_evpn_probe_neigh_on_mac_add(zevpn, mac);
+
+       /* Update seq number. */
+       n->rem_seq = seq;
+}
index 7520a515bb4fdcb26c4437231b8a8c86fd50370f..ddeb6ab8bad6502278354b3bf19a722dd7f07637 100644 (file)
@@ -275,19 +275,14 @@ void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt);
 void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt);
 void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
                                            void *ctxt);
+void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
+                                   struct ipaddr *ipaddr, zebra_mac_t *mac,
+                                   struct in_addr vtep_ip, uint8_t flags,
+                                   uint32_t seq);
 
-void zebra_evpn_probe_neigh_on_mac_add(zebra_evpn_t *zevpn, zebra_mac_t *zmac);
 zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn, struct ipaddr *ip,
                                    struct ethaddr *mac, zebra_mac_t *zmac,
                                    uint32_t n_flags);
-int zebra_evpn_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
-                                      zebra_mac_t *old_zmac,
-                                      zebra_mac_t *new_zmac,
-                                      zebra_neigh_t *nbr);
-void zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
-                                         zebra_neigh_t *nbr,
-                                         struct in_addr vtep_ip, bool do_dad,
-                                         bool *is_dup_detect, bool is_local);
 int zebra_evpn_neigh_uninstall(zebra_evpn_t *zevpn, zebra_neigh_t *n);
 void zebra_evpn_neigh_send_add_del_to_client(zebra_neigh_t *n,
                                             bool old_bgp_ready,
index 3ba4be855f4a45ef0c137a6c0ab6efda43b53605..5cb124682beae2ca4110d236e53c55ccaafc5f5e 100644 (file)
@@ -3345,19 +3345,10 @@ static void process_remote_macip_add(vni_t vni,
 {
        zebra_evpn_t *zevpn;
        zebra_vtep_t *zvtep;
-       zebra_mac_t *mac = NULL, *old_mac = NULL;
-       zebra_neigh_t *n = NULL;
-       int update_neigh = 0;
-       char buf[ETHER_ADDR_STRLEN];
-       char buf1[INET6_ADDRSTRLEN];
+       zebra_mac_t *mac = NULL;
        struct interface *ifp = NULL;
        struct zebra_if *zif = NULL;
        struct zebra_vrf *zvrf;
-       uint32_t tmp_seq;
-       bool is_router;
-       bool do_dad = false;
-       bool is_dup_detect = false;
-       bool old_static = false;
 
        /* Locate EVPN hash entry - expected to exist. */
        zevpn = zevpn_lookup(vni);
@@ -3410,8 +3401,6 @@ static void process_remote_macip_add(vni_t vni,
                }
        }
 
-       is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
-
        zvrf = vrf_info_lookup(zevpn->vxlan_if->vrf_id);
        if (!zvrf)
                return;
@@ -3422,147 +3411,8 @@ static void process_remote_macip_add(vni_t vni,
            != 0)
                return;
 
-       /* Check if the remote neighbor itself is unknown or has a
-        * change. If so, create or update and then install the entry.
-        */
-       n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
-       if (!n
-           || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
-           || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
-           || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0)
-           || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)
-           || seq != n->rem_seq)
-               update_neigh = 1;
-
-       if (update_neigh) {
-               if (!n) {
-                       n = zebra_evpn_neigh_add(zevpn, ipaddr, macaddr, mac,
-                                                0);
-                       if (!n) {
-                               zlog_warn(
-                                       "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
-                                       ipaddr2str(ipaddr, buf1,
-                                                  sizeof(buf1)),
-                                       prefix_mac2str(macaddr, buf,
-                                                      sizeof(buf)),
-                                       vni, inet_ntoa(vtep_ip));
-                               return;
-                       }
-
-               } else {
-                       const char *n_type;
-
-                       /* When host moves but changes its (MAC,IP)
-                        * binding, BGP may install a MACIP entry that
-                        * corresponds to "older" location of the host
-                        * in transient situations (because {IP1,M1}
-                        * is a different route from {IP1,M2}). Check
-                        * the sequence number and ignore this update
-                        * if appropriate.
-                        */
-                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-                               tmp_seq = n->loc_seq;
-                               n_type = "local";
-                       } else {
-                               tmp_seq = n->rem_seq;
-                               n_type = "remote";
-                       }
-                       if (seq < tmp_seq) {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
-                                       vni,
-                                       prefix_mac2str(macaddr,
-                                                      buf, sizeof(buf)),
-                                       " IP ",
-                                       ipaddr2str(ipaddr, buf1, sizeof(buf1)),
-                                       n_type,
-                                       tmp_seq);
-                               return;
-                       }
-                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-                               old_static = zebra_evpn_neigh_is_static(n);
-                               if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
-                                       zlog_debug("sync->remote neigh vni %u ip %s mac %s seq %d f0x%x",
-                                               n->zevpn->vni,
-                                               ipaddr2str(&n->ip, buf1,
-                                                       sizeof(buf1)),
-                                               prefix_mac2str(&n->emac, buf,
-                                                       sizeof(buf)),
-                                               seq, n->flags);
-                               zebra_evpn_neigh_clear_sync_info(n);
-                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
-                                       zebra_evpn_mac_send_del_to_client(
-                                               zevpn->vni, macaddr, mac->flags,
-                                               false /*force*/);
-                       }
-                       if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) {
-                               /* update neigh list for macs */
-                               old_mac =
-                                       zebra_evpn_mac_lookup(zevpn, &n->emac);
-                               if (old_mac) {
-                                       listnode_delete(old_mac->neigh_list, n);
-                                       n->mac = NULL;
-                                       zebra_evpn_deref_ip2mac(zevpn, old_mac);
-                               }
-                               n->mac = mac;
-                               listnode_add_sort(mac->neigh_list, n);
-                               memcpy(&n->emac, macaddr, ETH_ALEN);
-
-                               /* Check Neigh's curent state is local
-                                * (this is the case where neigh/host has  moved
-                                * from L->R) and check previous detction
-                                * started via local learning.
-                                *
-                                * RFC-7432: A PE/VTEP that detects a MAC
-                                * mobilit event via local learning starts
-                                * an M-second timer.
-                                * VTEP-IP or seq. change along is not
-                                * considered for dup. detection.
-                                *
-                                * Mobilty event scenario-B IP-MAC binding
-                                * changed.
-                                */
-                               if ((!CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
-                                   && n->dad_count)
-                                       do_dad = true;
-
-                       }
-               }
-
-               /* Set "remote" forwarding info. */
-               UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_LOCAL_FLAGS);
-               n->r_vtep_ip = vtep_ip;
-               SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
-
-               /* Set router flag (R-bit) to this Neighbor entry */
-               if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
-                       SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
-               else
-                       UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
-
-               /* Check old or new MAC detected as duplicate,
-                * inherit duplicate flag to this neigh.
-                */
-               if (zebra_evpn_ip_inherit_dad_from_mac(zvrf, old_mac, mac, n)) {
-                       flog_warn(EC_ZEBRA_DUP_IP_INHERIT_DETECTED,
-                               "VNI %u: MAC %s IP %s detected as duplicate during remote update, inherit duplicate from MAC",
-                               zevpn->vni,
-                               prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
-                               ipaddr2str(&n->ip, buf1, sizeof(buf1)));
-               }
-
-               /* Check duplicate address detection for IP */
-               zebra_evpn_dup_addr_detect_for_neigh(
-                       zvrf, n, n->r_vtep_ip, do_dad, &is_dup_detect, false);
-               /* Install the entry. */
-               if (!is_dup_detect)
-                       zebra_evpn_rem_neigh_install(zevpn, n, old_static);
-       }
-
-       zebra_evpn_probe_neigh_on_mac_add(zevpn, mac);
-
-       /* Update seq number. */
-       n->rem_seq = seq;
+       process_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac, vtep_ip, flags,
+                                      seq);
 }
 
 /* Process a remote MACIP delete from BGP. */