]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_addpath.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgp_addpath.c
index 75fdb0bb445c91f6b03c3d25560392847b748a0f..7f746541ff243fa8d74a83aa364315c0ef807886 100644 (file)
@@ -1,20 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Addpath TX ID selection, and related utilities
  * Copyright (C) 2018  Amazon.com, Inc. or its affiliates
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifdef HAVE_CONFIG_H
@@ -80,14 +67,12 @@ void bgp_addpath_init_bgp_data(struct bgp_addpath_bgp_data *d)
        afi_t afi;
        int i;
 
-       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
-                       for (i = 0; i < BGP_ADDPATH_MAX; i++) {
-                               d->id_allocators[afi][safi][i] = NULL;
-                               d->peercount[afi][safi][i] = 0;
-                       }
-                       d->total_peercount[afi][safi] = 0;
+       FOREACH_AFI_SAFI (afi, safi) {
+               for (i = 0; i < BGP_ADDPATH_MAX; i++) {
+                       d->id_allocators[afi][safi][i] = NULL;
+                       d->peercount[afi][safi][i] = 0;
                }
+               d->total_peercount[afi][safi] = 0;
        }
 }
 
@@ -113,6 +98,9 @@ void bgp_addpath_free_info_data(struct bgp_addpath_info_data *d,
 uint32_t bgp_addpath_id_for_peer(struct peer *peer, afi_t afi, safi_t safi,
                                struct bgp_addpath_info_data *d)
 {
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
        if (peer->addpath_type[afi][safi] < BGP_ADDPATH_MAX)
                return d->addpath_tx_id[peer->addpath_type[afi][safi]];
        else
@@ -173,21 +161,26 @@ bool bgp_addpath_tx_path(enum bgp_addpath_strat strat, struct bgp_path_info *pi)
                        return true;
                else
                        return false;
-       default:
+       case BGP_ADDPATH_MAX:
                return false;
        }
+
+       assert(!"Reached end of function we should never hit");
 }
 
 static void bgp_addpath_flush_type_rn(struct bgp *bgp, afi_t afi, safi_t safi,
                                      enum bgp_addpath_strat addpath_type,
-                                     struct bgp_node *rn)
+                                     struct bgp_dest *dest)
 {
        struct bgp_path_info *pi;
 
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
        idalloc_drain_pool(
                bgp->tx_addpath.id_allocators[afi][safi][addpath_type],
-               &(rn->tx_addpath.free_ids[addpath_type]));
-       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
+               &(dest->tx_addpath.free_ids[addpath_type]));
+       for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
                if (pi->tx_addpath.addpath_tx_id[addpath_type]
                    != IDALLOC_INVALID) {
                        idalloc_free(
@@ -210,24 +203,27 @@ static void bgp_addpath_flush_type_rn(struct bgp *bgp, afi_t afi, safi_t safi,
 static void bgp_addpath_flush_type(struct bgp *bgp, afi_t afi, safi_t safi,
                                   enum bgp_addpath_strat addpath_type)
 {
-       struct bgp_node *rn, *nrn;
+       struct bgp_dest *dest, *ndest;
 
-       for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
-            rn = bgp_route_next(rn)) {
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
+       for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
+            dest = bgp_route_next(dest)) {
                if (safi == SAFI_MPLS_VPN) {
                        struct bgp_table *table;
 
-                       table = bgp_node_get_bgp_table_info(rn);
+                       table = bgp_dest_get_bgp_table_info(dest);
                        if (!table)
                                continue;
 
-                       for (nrn = bgp_table_top(table); nrn;
-                            nrn = bgp_route_next(nrn))
+                       for (ndest = bgp_table_top(table); ndest;
+                            ndest = bgp_route_next(ndest))
                                bgp_addpath_flush_type_rn(bgp, afi, safi,
-                                                         addpath_type, nrn);
+                                                         addpath_type, ndest);
                } else {
                        bgp_addpath_flush_type_rn(bgp, afi, safi, addpath_type,
-                                                 rn);
+                                                 dest);
                }
        }
 
@@ -253,14 +249,18 @@ static void bgp_addpath_populate_path(struct id_alloc *allocator,
  * and afi/safi combination. Since we won't waste the time computing addpath IDs
  * for unused strategies, the first time a peer is configured to use a strategy,
  * we have to backfill the data.
+ * In labeled-unicast, addpath allocations SHOULD be done in unicast SAFI.
  */
 static void bgp_addpath_populate_type(struct bgp *bgp, afi_t afi, safi_t safi,
                                    enum bgp_addpath_strat addpath_type)
 {
-       struct bgp_node *rn, *nrn;
+       struct bgp_dest *dest, *ndest;
        char buf[200];
        struct id_alloc *allocator;
 
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
        snprintf(buf, sizeof(buf), "Addpath ID Allocator %s:%d/%d",
                 bgp_addpath_names(addpath_type)->config_name, (int)afi,
                 (int)safi);
@@ -276,25 +276,25 @@ static void bgp_addpath_populate_type(struct bgp *bgp, afi_t afi, safi_t safi,
 
        allocator = bgp->tx_addpath.id_allocators[afi][safi][addpath_type];
 
-       for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
-            rn = bgp_route_next(rn)) {
+       for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
+            dest = bgp_route_next(dest)) {
                struct bgp_path_info *bi;
 
                if (safi == SAFI_MPLS_VPN) {
                        struct bgp_table *table;
 
-                       table = bgp_node_get_bgp_table_info(rn);
+                       table = bgp_dest_get_bgp_table_info(dest);
                        if (!table)
                                continue;
 
-                       for (nrn = bgp_table_top(table); nrn;
-                            nrn = bgp_route_next(nrn))
-                               for (bi = bgp_node_get_bgp_path_info(nrn); bi;
+                       for (ndest = bgp_table_top(table); ndest;
+                            ndest = bgp_route_next(ndest))
+                               for (bi = bgp_dest_get_bgp_path_info(ndest); bi;
                                     bi = bi->next)
                                        bgp_addpath_populate_path(allocator, bi,
                                                                  addpath_type);
                } else {
-                       for (bi = bgp_node_get_bgp_path_info(rn); bi;
+                       for (bi = bgp_dest_get_bgp_path_info(dest); bi;
                             bi = bi->next)
                                bgp_addpath_populate_path(allocator, bi,
                                                          addpath_type);
@@ -359,11 +359,15 @@ void bgp_addpath_set_peer_type(struct peer *peer, afi_t afi, safi_t safi,
                              enum bgp_addpath_strat addpath_type)
 {
        struct bgp *bgp = peer->bgp;
-       enum bgp_addpath_strat old_type = peer->addpath_type[afi][safi];
+       enum bgp_addpath_strat old_type;
        struct listnode *node, *nnode;
        struct peer *tmp_peer;
        struct peer_group *group;
 
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
+       old_type = peer->addpath_type[afi][safi];
        if (addpath_type == old_type)
                return;
 
@@ -391,9 +395,9 @@ void bgp_addpath_set_peer_type(struct peer *peer, afi_t afi, safi_t safi,
                }
        }
 
-       zlog_info("Resetting peer %s%s due to change in addpath config",
+       zlog_info("Resetting peer %s%pBP due to change in addpath config",
                  CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) ? "group " : "",
-                 peer->host);
+                 peer);
 
        if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
                group = peer->group;
@@ -426,13 +430,16 @@ void bgp_addpath_set_peer_type(struct peer *peer, afi_t afi, safi_t safi,
  * best-per-as updates from needing to do a separate withdraw and update just to
  * swap out which path is sent.
  */
-void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_node *bn, afi_t afi,
-                         safi_t safi)
+void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_dest *bn, afi_t afi,
+                           safi_t safi)
 {
        int i;
        struct bgp_path_info *pi;
        struct id_alloc_pool **pool_ptr;
 
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
        for (i = 0; i < BGP_ADDPATH_MAX; i++) {
                struct id_alloc *alloc =
                        bgp->tx_addpath.id_allocators[afi][safi][i];
@@ -442,7 +449,7 @@ void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_node *bn, afi_t afi,
                        continue;
 
                /* Free Unused IDs back to the pool.*/
-               for (pi = bgp_node_get_bgp_path_info(bn); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(bn); pi; pi = pi->next) {
                        if (pi->tx_addpath.addpath_tx_id[i] != IDALLOC_INVALID
                            && !bgp_addpath_tx_path(i, pi)) {
                                idalloc_free_to_pool(pool_ptr,
@@ -453,7 +460,7 @@ void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_node *bn, afi_t afi,
                }
 
                /* Give IDs to paths that need them (pulling from the pool) */
-               for (pi = bgp_node_get_bgp_path_info(bn); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(bn); pi; pi = pi->next) {
                        if (pi->tx_addpath.addpath_tx_id[i] == IDALLOC_INVALID
                            && bgp_addpath_tx_path(i, pi)) {
                                pi->tx_addpath.addpath_tx_id[i] =