]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Fix neighbor update to BGP
authorvivek <vivek@cumulusnetworks.com>
Mon, 10 Sep 2018 17:19:41 +0000 (10:19 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 18 Sep 2018 14:41:53 +0000 (10:41 -0400)
Ensure that when the is_router condition changes for a locally learnt
neighbor, it is informed to BGP only if it is active i.e., the MAC is
also locally learnt.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Chirag Shah <chirag@cumulusnetworks.com>
Ticket: CM-22288
Reviewed By: CCR-7832
Testing Done:
1. Failed test
2. vxlan_routing_test.py

zebra/zebra_vxlan.c

index c6136dfa3ad887f540308cbdb35718052955f2af..397bfaec93a4aa36347b20ff75dc3044a9926138 100644 (file)
@@ -2028,51 +2028,60 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                check_rbit = true;
        } else {
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-                       /* If there is no MAC change, BGP isn't interested. */
-                       if (is_router !=
-                           (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
-                                       ? 1 : 0))
-                               check_rbit = true;
-
-                       if (memcmp(n->emac.octet, macaddr->octet,
-                                  ETH_ALEN) == 0) {
-                               /* Update any params and return - client doesn't
-                                * care about a purely local change.
-                                */
+                       bool mac_different;
+                       bool cur_is_router;
+
+                       /* Note any changes and see if of interest to BGP. */
+                       mac_different = (memcmp(n->emac.octet,
+                                       macaddr->octet, ETH_ALEN) != 0) ? 1 : 0;
+                       cur_is_router = !!CHECK_FLAG(n->flags,
+                                                    ZEBRA_NEIGH_ROUTER_FLAG);
+                       if (!mac_different && is_router == cur_is_router) {
                                n->ifindex = ifp->ifindex;
-                       } else {
+                               return 0;
+                       }
 
-                               /* If the MAC has changed, need to issue a
-                                * delete first as this means a different
-                                * MACIP route. Also, need to do some
-                                * unlinking/relinking. We also need to
-                                * update the MAC's sequence number
-                                * in different situations.
-                                */
-                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
-                                       zvni_neigh_send_del_to_client(
-                                               zvni->vni, &n->ip, &n->emac, 0);
-                               old_zmac = zvni_mac_lookup(zvni, &n->emac);
-                               if (old_zmac) {
-                                       old_mac_seq =
-                                               CHECK_FLAG(old_zmac->flags,
-                                                          ZEBRA_MAC_REMOTE) ?
-                                                       old_zmac->rem_seq :
-                                                       old_zmac->loc_seq;
-                                       neigh_mac_change = upd_mac_seq = true;
-                                       listnode_delete(
-                                               old_zmac->neigh_list, n);
-                                       zvni_deref_ip2mac(zvni, old_zmac);
-                               }
+                       if (!mac_different) {
+                               /* Only the router flag has changed. */
+                               if (is_router)
+                                       SET_FLAG(n->flags,
+                                               ZEBRA_NEIGH_ROUTER_FLAG);
+                               else
+                                       UNSET_FLAG(n->flags,
+                                               ZEBRA_NEIGH_ROUTER_FLAG);
 
-                               /* Update the forwarding info. */
-                               n->ifindex = ifp->ifindex;
-                               memcpy(&n->emac, macaddr, ETH_ALEN);
+                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
+                                       return zvni_neigh_send_add_to_client(
+                                                       zvni->vni, ip, macaddr,
+                                                       n->flags, n->loc_seq);
+                               return 0;
+                       }
 
-                               /* Link to new MAC */
-                               listnode_add_sort(zmac->neigh_list, n);
+                       /* The MAC has changed, need to issue a delete
+                        * first as this means a different MACIP route.
+                        * Also, need to do some unlinking/relinking.
+                        * We also need to update the MAC's sequence number
+                        * in different situations.
+                        */
+                       if (IS_ZEBRA_NEIGH_ACTIVE(n))
+                               zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
+                                                             &n->emac, 0);
+                       old_zmac = zvni_mac_lookup(zvni, &n->emac);
+                       if (old_zmac) {
+                               old_mac_seq = CHECK_FLAG(old_zmac->flags,
+                                                        ZEBRA_MAC_REMOTE) ?
+                                       old_zmac->rem_seq : old_zmac->loc_seq;
+                               neigh_mac_change = upd_mac_seq = true;
+                               listnode_delete(old_zmac->neigh_list, n);
+                               zvni_deref_ip2mac(zvni, old_zmac);
                        }
 
+                       /* Update the forwarding info. */
+                       n->ifindex = ifp->ifindex;
+                       memcpy(&n->emac, macaddr, ETH_ALEN);
+
+                       /* Link to new MAC */
+                       listnode_add_sort(zmac->neigh_list, n);
                } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
                        /*
                         * Neighbor has moved from remote to local. Its