summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-05-26 19:05:12 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-05-28 18:38:27 +0200
commit1d6b9953ad3b7cbfe593da06aac435c95e562a30 (patch)
tree76d2d950f6d4c1596062b7992a796b04030ff3e2
parentb74c333413dfeaff5fb6007981c41c5fcfe8cb4c (diff)
downloadNetworkManager-1d6b9953ad3b7cbfe593da06aac435c95e562a30.tar.gz
device: set accept_ra to 1 when changing IPv6 kernel token
Setting the kernel token is not strictly necessary as the IPv6 address is generated in userspace by NetworkManager. However it is convenient for users to see that the value set in the profile is also set in the kernel, to confirm that everything is working as expected. The kernel allows setting a token only when 'accept_ra' is 1: temporarily flip it if necessary. Unfortunately this will also generate an additional Router Solicitation from kernel, but this is not a big issue.
-rw-r--r--src/devices/nm-device.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index dc46d3f7cc..1a3efaefec 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1509,6 +1509,50 @@ nm_device_sysctl_ip_conf_get_int_checked (NMDevice *self,
fallback);
}
+static void
+set_ipv6_token (NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str)
+{
+ NMPlatform *platform;
+ int ifindex;
+ const NMPlatformLink *link;
+ char buf[32];
+ gint64 val;
+
+ /* Setting the kernel token is not strictly necessary as the
+ * IPv6 address is generated in userspace. However it is
+ * convenient so that users can see the token with iproute
+ * ('ip token'). */
+ platform = nm_device_get_platform (self);
+ ifindex = nm_device_get_ip_ifindex (self);
+ link = nm_platform_link_get (platform, ifindex);
+
+ if (link && link->inet6_token.id == iid.id) {
+ _LOGT (LOGD_DEVICE | LOGD_IP6, "token %s already set", token_str);
+ return;
+ }
+
+ /* The kernel allows setting a token only when 'accept_ra'
+ * is 1: temporarily flip it if necessary; unfortunately
+ * this will also generate an additional Router Solicitation
+ * from kernel. */
+ val = nm_device_sysctl_ip_conf_get_int_checked (self,
+ AF_INET6,
+ "accept_ra",
+ 10,
+ G_MININT32,
+ G_MAXINT32,
+ 1);
+ if (val != 1)
+ nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "1");
+
+ nm_platform_link_set_ipv6_token (platform, ifindex, iid);
+
+ if (val != 1) {
+ nm_sprintf_buf (buf, "%d", (int) val);
+ nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", buf);
+ }
+}
+
gboolean
nm_device_sysctl_ip_conf_set (NMDevice *self,
int addr_family,
@@ -8178,23 +8222,13 @@ ip_config_merge_and_apply (NMDevice *self,
}
if (!IS_IPv4) {
- const NMPlatformLink *link;
NMUtilsIPv6IfaceId iid;
- NMPlatform *platform;
- int ifindex;
if ( commit
&& priv->ndisc_started
&& ip6_addr_gen_token
&& nm_utils_ipv6_interface_identifier_get_from_token (&iid, ip6_addr_gen_token)) {
- platform = nm_device_get_platform (self);
- ifindex = nm_device_get_ip_ifindex (self);
- link = nm_platform_link_get (platform, ifindex);
-
- if (link && link->inet6_token.id == iid.id)
- _LOGT (LOGD_DEVICE | LOGD_IP6, "token %s already set", ip6_addr_gen_token);
- else
- nm_platform_link_set_ipv6_token (platform, ifindex, iid);
+ set_ipv6_token (self, iid, ip6_addr_gen_token);
}
}