]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: fix the IGP metric for best path selection on VPN import
authorLouis Scalbert <louis.scalbert@6wind.com>
Mon, 14 Feb 2022 13:18:10 +0000 (14:18 +0100)
committerLouis Scalbert <louis.scalbert@6wind.com>
Thu, 15 Dec 2022 16:09:35 +0000 (17:09 +0100)
Since the commit da0c0ef70c ("bgpd: VRF-Lite fix best path selection"),
the best path selection is made from the comparison of the attributes
of the original route i.e. the ultimate path.

The IGP metric is currently set on the child path instead of the
ultimate path (i.e. the parent path). On eBGP, the ultimate path is the
child path. However, for imported routes, the ultimate path is always
set to 0, which results in skipping the IGP metric comparison when
selecting the best path.

Set the IGP metric on the ultimate path when a BGP nexthop is added or
updated.

Fixes: da0c0ef70c ("bgpd: VRF-Lite fix best path selection")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
bgpd/bgp_nht.c

index e387cdd488893356ce1b17548586af10c2804ab1..cf8ff524e963b2d79ef7988c55819fc4d3e8f507 100644 (file)
@@ -294,6 +294,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
 {
        struct bgp_nexthop_cache_head *tree = NULL;
        struct bgp_nexthop_cache *bnc;
+       struct bgp_path_info *bpi_ultimate;
        struct prefix p;
        uint32_t srte_color = 0;
        int is_bgp_static_route = 0;
@@ -450,10 +451,12 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
                /* updates NHT pi list reference */
                path_nh_map(pi, bnc, true);
 
+               bpi_ultimate = bgp_get_imported_bpi_ultimate(pi);
                if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
-                       (bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
-               else if (pi->extra)
-                       pi->extra->igpmetric = 0;
+                       (bgp_path_info_extra_get(bpi_ultimate))->igpmetric =
+                               bnc->metric;
+               else if (bpi_ultimate->extra)
+                       bpi_ultimate->extra->igpmetric = 0;
        } else if (peer) {
                /*
                 * Let's not accidentally save the peer data for a peer
@@ -1123,6 +1126,7 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
 {
        struct bgp_dest *dest;
        struct bgp_path_info *path;
+       struct bgp_path_info *bpi_ultimate;
        int afi;
        struct peer *peer = (struct peer *)bnc->nht_info;
        struct bgp_table *table;
@@ -1222,11 +1226,12 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
 
                /* Copy the metric to the path. Will be used for bestpath
                 * computation */
+               bpi_ultimate = bgp_get_imported_bpi_ultimate(path);
                if (bgp_isvalid_nexthop(bnc) && bnc->metric)
-                       (bgp_path_info_extra_get(path))->igpmetric =
+                       (bgp_path_info_extra_get(bpi_ultimate))->igpmetric =
                                bnc->metric;
-               else if (path->extra)
-                       path->extra->igpmetric = 0;
+               else if (bpi_ultimate->extra)
+                       bpi_ultimate->extra->igpmetric = 0;
 
                if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
                    || CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED)