diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-02-10 20:38:56 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-10 20:38:56 +0900 |
commit | ac7e18be76a6069e29b01d13152256bc195cb639 (patch) | |
tree | 6d41166b165bf66d1c7652d9df96e014beaf81b6 /src/network/networkd-setlink.c | |
parent | 19ff06b3a4cb2a2e1612e5774f75a145995b4849 (diff) | |
parent | 2becdbccd1a8d377c67f3f00c6e34cf3e53e87c7 (diff) | |
download | systemd-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.c | 45 |
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) |