diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-05-26 19:05:12 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-05-28 18:38:27 +0200 |
commit | 1d6b9953ad3b7cbfe593da06aac435c95e562a30 (patch) | |
tree | 76d2d950f6d4c1596062b7992a796b04030ff3e2 | |
parent | b74c333413dfeaff5fb6007981c41c5fcfe8cb4c (diff) | |
download | NetworkManager-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.c | 56 |
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); } } |