]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_mac.c
bgpd: Adding BGP GR Global & Per Neighbour FSM changes
[mirror_frr.git] / bgpd / bgp_mac.c
index c85b4b1f39891fdef06a32dfd86ea918e81c0d25..537bb45455e8c2357485fc88f4c22389a4789436 100644 (file)
@@ -134,11 +134,11 @@ static struct bgp_self_mac *bgp_mac_find_interface_name(const char *ifname)
 }
 
 static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
-                                        struct bgp_table *table)
+                                        struct bgp_table *table,
+                                        struct ethaddr *macaddr)
 {
        struct bgp_node *prn, *rn;
        struct bgp_path_info *pi;
-       uint32_t count = 0;
 
        for (prn = bgp_table_top(table); prn; prn = bgp_route_next(prn)) {
                struct bgp_table *sub = prn->info;
@@ -147,12 +147,21 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
                        continue;
 
                for (rn = bgp_table_top(sub); rn; rn = bgp_route_next(rn)) {
+                       bool rn_affected;
+                       struct prefix_evpn *pevpn = (struct prefix_evpn *)&rn->p;
                        struct prefix_rd prd;
                        uint32_t num_labels = 0;
                        mpls_label_t *label_pnt = NULL;
                        struct bgp_route_evpn evpn;
 
-                       count++;
+                       if (pevpn->family == AF_EVPN &&
+                           pevpn->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+                           memcmp(&rn->p.u.prefix_evpn.macip_addr.mac,
+                                  macaddr, ETH_ALEN) == 0)
+                               rn_affected = true;
+                       else
+                               rn_affected = false;
+
                        for (pi = rn->info; pi; pi = pi->next) {
                                if (pi->peer == peer)
                                        break;
@@ -161,6 +170,14 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
                        if (!pi)
                                continue;
 
+                       /*
+                        * If the mac address is not the same then
+                        * we don't care and since we are looking
+                        */
+                       if ((memcmp(&pi->attr->rmac, macaddr, ETH_ALEN) != 0) &&
+                           !rn_affected)
+                               continue;
+
                        if (pi->extra)
                                num_labels = pi->extra->num_labels;
                        if (num_labels)
@@ -202,7 +219,7 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
        }
 }
 
-static void bgp_mac_rescan_evpn_table(struct bgp *bgp)
+static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr)
 {
        struct listnode *node;
        struct peer *peer;
@@ -232,12 +249,12 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp)
                        if (bgp_debug_update(peer, NULL, NULL, 1))
                                zlog_debug("Processing EVPN MAC interface change on peer %s",
                                           peer->host);
-                       bgp_process_mac_rescan_table(bgp, peer, table);
+                       bgp_process_mac_rescan_table(bgp, peer, table, macaddr);
                }
        }
 }
 
-static void bgp_mac_rescan_all_evpn_tables(void)
+static void bgp_mac_rescan_all_evpn_tables(struct ethaddr *macaddr)
 {
        struct listnode *node;
        struct bgp *bgp;
@@ -246,11 +263,12 @@ static void bgp_mac_rescan_all_evpn_tables(void)
                struct bgp_table *table = bgp->rib[AFI_L2VPN][SAFI_EVPN];
 
                if (table)
-                       bgp_mac_rescan_evpn_table(bgp);
+                       bgp_mac_rescan_evpn_table(bgp, macaddr);
        }
 }
 
-static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname)
+static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname,
+                                       struct ethaddr *macaddr)
 {
        struct listnode *node = NULL;
        char *name;
@@ -266,11 +284,13 @@ static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname)
        }
 
        if (bsm->ifp_list->count == 0) {
+               struct ethaddr mac = *macaddr;
+
                hash_release(bm->self_mac_hash, bsm);
                list_delete(&bsm->ifp_list);
                XFREE(MTYPE_BSM, bsm);
 
-               bgp_mac_rescan_all_evpn_tables();
+               bgp_mac_rescan_all_evpn_tables(&mac);
        }
 }
 
@@ -294,7 +314,8 @@ void bgp_mac_add_mac_entry(struct interface *ifp)
 
                listnode_add(bsm->ifp_list, ifname);
                if (old_bsm)
-                       bgp_mac_remove_ifp_internal(old_bsm, ifname);
+                       bgp_mac_remove_ifp_internal(old_bsm, ifname,
+                                                   &old_bsm->macaddr);
        } else {
                /*
                 * If old mac address is the same as the new,
@@ -306,12 +327,13 @@ void bgp_mac_add_mac_entry(struct interface *ifp)
                }
 
                if (old_bsm)
-                       bgp_mac_remove_ifp_internal(old_bsm, ifp->name);
+                       bgp_mac_remove_ifp_internal(old_bsm, ifp->name,
+                                                   &old_bsm->macaddr);
 
                listnode_add(bsm->ifp_list, ifname);
        }
 
-       bgp_mac_rescan_all_evpn_tables();
+       bgp_mac_rescan_all_evpn_tables(&bsm->macaddr);
 }
 
 void bgp_mac_del_mac_entry(struct interface *ifp)
@@ -328,7 +350,7 @@ void bgp_mac_del_mac_entry(struct interface *ifp)
         * Write code to allow old mac address to no-longer
         * win if we happen to have received it from a peer.
         */
-       bgp_mac_remove_ifp_internal(bsm, ifp->name);
+       bgp_mac_remove_ifp_internal(bsm, ifp->name, &bsm->macaddr);
 }
 
 /* This API checks MAC address against any of local