summaryrefslogtreecommitdiff
path: root/src/network/networkd-setlink.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-02-10 20:38:56 +0900
committerGitHub <noreply@github.com>2022-02-10 20:38:56 +0900
commitac7e18be76a6069e29b01d13152256bc195cb639 (patch)
tree6d41166b165bf66d1c7652d9df96e014beaf81b6 /src/network/networkd-setlink.c
parent19ff06b3a4cb2a2e1612e5774f75a145995b4849 (diff)
parent2becdbccd1a8d377c67f3f00c6e34cf3e53e87c7 (diff)
downloadsystemd-ac7e18be76a6069e29b01d13152256bc195cb639.tar.gz
Merge pull request #22452 from yuwata/network-ipv6ll
network: use sysctl to set IPv6LL address generation mode when the interface is already up
Diffstat (limited to 'src/network/networkd-setlink.c')
-rw-r--r--src/network/networkd-setlink.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c
index 4292f8976f..542f20c54d 100644
--- a/src/network/networkd-setlink.c
+++ b/src/network/networkd-setlink.c
@@ -228,23 +228,7 @@ static int link_configure_fill_message(
switch (op) {
case SET_LINK_ADDRESS_GENERATION_MODE:
- r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
- if (r < 0)
- return r;
-
- r = sd_netlink_message_open_container(req, AF_INET6);
- if (r < 0)
- return r;
-
- r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, PTR_TO_UINT8(userdata));
- if (r < 0)
- return r;
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return r;
-
- r = sd_netlink_message_close_container(req);
+ r = ipv6ll_addrgen_mode_fill_message(req, PTR_TO_UINT8(userdata));
if (r < 0)
return r;
break;
@@ -695,8 +679,8 @@ static int link_request_set_link(
}
int link_request_to_set_addrgen_mode(Link *link) {
+ IPv6LinkLocalAddressGenMode mode;
Request *req;
- uint8_t mode;
int r;
assert(link);
@@ -705,14 +689,23 @@ int link_request_to_set_addrgen_mode(Link *link) {
if (!socket_ipv6_is_supported())
return 0;
- if (!link_ipv6ll_enabled(link))
- mode = IN6_ADDR_GEN_MODE_NONE;
- else if (link->network->ipv6ll_address_gen_mode >= 0)
- mode = link->network->ipv6ll_address_gen_mode;
- else if (in6_addr_is_set(&link->network->ipv6ll_stable_secret))
- mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
- else
- mode = IN6_ADDR_GEN_MODE_EUI64;
+ mode = link_get_ipv6ll_addrgen_mode(link);
+
+ if (mode == link->ipv6ll_address_gen_mode)
+ return 0;
+
+ /* If the link is already up, then changing the mode by netlink does not take effect until the
+ * link goes down. Hence, we need to reset the interface. However, setting the mode by sysctl
+ * does not need that. Let's use the sysctl interface when the link is already up.
+ * See also issue #22424. */
+ if (mode != IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE &&
+ FLAGS_SET(link->flags, IFF_UP)) {
+ r = link_set_ipv6ll_addrgen_mode(link, mode);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot set IPv6 address generation mode, ignoring: %m");
+
+ return 0;
+ }
r = link_request_set_link(link, SET_LINK_ADDRESS_GENERATION_MODE, link_set_addrgen_mode_handler, &req);
if (r < 0)