summaryrefslogtreecommitdiff
path: root/src/nm-ip6-config.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-10-09 10:58:47 +0200
committerThomas Haller <thaller@redhat.com>2017-10-12 10:38:19 +0200
commit032b4e4371abf7c8b353d4c03a9b4b5c316532f4 (patch)
tree6b23862a18725c5dba3ae7d4d8b6c6feb6ef3ef4 /src/nm-ip6-config.c
parent0a972a46671aca0cbae29f88dc033172ec76c72a (diff)
downloadNetworkManager-032b4e4371abf7c8b353d4c03a9b4b5c316532f4.tar.gz
core: use router preference for IPv6 routes
For routes and the default-route from NDisc, set the router preference RTA_PREF. Also, previously, we would only configure one IPv6 default-route. That by itself was not really a problem, as long as NetworkManager would always make sure that it configured the route to the ~best~ router. Actually, NM should have done that already. It keeps the list of gateways sorted, and prefers them according to their preference. But maybe it didn't, so we have bug rh#1445417 (??). Change that by configuring a default-route for all gateways, with appropriate router prefrence. In case, kernel doesn't support RTA_PREF yet, only configure all routes that share the same maxiumum preference. https://bugzilla.redhat.com/show_bug.cgi?id=1445417
Diffstat (limited to 'src/nm-ip6-config.c')
-rw-r--r--src/nm-ip6-config.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index 8eeabca223..3f0bbfe75c 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -1769,7 +1769,8 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
const NMNDiscRoute *routes,
guint routes_n,
guint32 route_table,
- guint32 route_metric)
+ guint32 route_metric,
+ gboolean kernel_support_rta_pref)
{
NMIP6ConfigPrivate *priv;
guint i;
@@ -1800,6 +1801,8 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
r->rt_source = NM_IP_CONFIG_SOURCE_NDISC;
r->table_coerced = nm_platform_route_table_coerce (route_table);
r->metric = route_metric;
+ r->rt_pref = ndisc_route->preference;
+ nm_assert ((NMIcmpv6RouterPref) r->rt_pref == ndisc_route->preference);
if (_nm_ip_config_add_obj (priv->multi_idx,
&priv->idx_ip6_routes_,
@@ -1814,28 +1817,40 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
}
- /* Use the first gateway as ordered in neighbor discovery cache. */
if (gateways_n) {
const NMPObject *obj_new;
- const NMPlatformIP6Route r = {
+ NMPlatformIP6Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
.ifindex = priv->ifindex,
- .gateway = gateways[0].address,
.table_coerced = nm_platform_route_table_coerce (route_table),
.metric = route_metric,
};
+ const NMIcmpv6RouterPref first_pref = gateways[0].preference;
+
+ for (i = 0; i < gateways_n; i++) {
+ r.gateway = gateways[i].address;
+ r.rt_pref = gateways[i].preference;
+ nm_assert ((NMIcmpv6RouterPref) r.rt_pref == gateways[i].preference);
+ if (_nm_ip_config_add_obj (priv->multi_idx,
+ &priv->idx_ip6_routes_,
+ priv->ifindex,
+ NULL,
+ (const NMPlatformObject *) &r,
+ FALSE,
+ TRUE,
+ NULL,
+ &obj_new))
+ changed = TRUE;
+ new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
- if (_nm_ip_config_add_obj (priv->multi_idx,
- &priv->idx_ip6_routes_,
- priv->ifindex,
- NULL,
- (const NMPlatformObject *) &r,
- FALSE,
- TRUE,
- NULL,
- &obj_new))
- changed = TRUE;
- new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
+ if ( first_pref != gateways[i].preference
+ && !kernel_support_rta_pref) {
+ /* We are unable to configure a router preference. Hence, we skip all gateways
+ * with a different preference from the first gateway. Note, that the gateways
+ * are sorted in order of highest to lowest preference. */
+ break;
+ }
+ }
}
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)