about summary refs log tree commit diff
path: root/src/core/ndisc
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2024-08-09 18:57:26 +0200
committerMichael Biebl <biebl@debian.org>2024-08-09 18:57:26 +0200
commit5ebc16389d33662f712e49a8d5f3445f6b34ca05 (patch)
treeaf14aec1d1271903e73ef2b45d6b9c6d6c188f44 /src/core/ndisc
parentf07580d7a481ecbc1e90033b7fa5607e0ab2d051 (diff)
parente96d74409128c6a977e31f24fad9b267d2feb9a1 (diff)
Update upstream source from tag 'upstream/1.48.8'
Update to upstream version '1.48.8'
with Debian dir b9f8c1b806c3088cd4a6040531628e5352ccb2ee
Diffstat (limited to 'src/core/ndisc')
-rw-r--r--src/core/ndisc/nm-ndisc.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c
index ca646a6d..4800829f 100644
--- a/src/core/ndisc/nm-ndisc.c
+++ b/src/core/ndisc/nm-ndisc.c
@@ -170,6 +170,9 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex        *multi_idx,
     }
 
     if (rdata->gateways_n > 0) {
+        guint              metric_offset = 0;
+        NMIcmpv6RouterPref prev_pref     = NM_ICMPV6_ROUTER_PREF_INVALID;
+
         NMPlatformIP6Route r = {
             .rt_source     = NM_IP_CONFIG_SOURCE_NDISC,
             .ifindex       = ifindex,
@@ -180,6 +183,20 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex        *multi_idx,
         };
 
         for (i = 0; i < rdata->gateways_n; i++) {
+            /* If we add multiple default routes with the same metric and
+             * different preferences, kernel merges them into a single ECMP
+             * route, with overall preference equal to the preference of the
+             * first route added. Therefore, the preference of individual routes
+             * is not respected.
+             * To avoid that, add routes with different metrics if they have
+             * different preferences, so that they are not merged together. Here
+             * the gateways are already ordered by increasing preference. */
+            if (i != 0 && rdata->gateways[i].preference != prev_pref) {
+                metric_offset++;
+            }
+
+            prev_pref = rdata->gateways[i].preference;
+            r.metric  = metric_offset;
             r.gateway = rdata->gateways[i].address;
             r.rt_pref = rdata->gateways[i].preference;
             nm_assert((NMIcmpv6RouterPref) r.rt_pref == rdata->gateways[i].preference);