mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
network: attempt to trigger kernel IPv6LL address generation
Try to ensure kernel IPv6 link local address generation occurs by setting the per-if addr_gen_mode sysctl when the link is already up, instead of the netlink interface (IFLA_INET6_ADDR_GEN_MODE). The netlink setting is sufficient in cases where the interface is not yet up when networkd configures an interface - bringing the interface up will trigger in-kernel address generation. If the interface is already up, yet the interface has no IPv6LL assigned setting IFLA_INET6_ADDR_GEN_MODE has no effect. Writing the addr_gen_mode sysctl is a best effort attempt at triggering address generation regardless of interface state because it also works in cases where the interface is already up. Fixes #22424.
This commit is contained in:
parent
2b25f4eb23
commit
77d65e5659
@ -223,6 +223,16 @@ int link_set_ipv6ll_stable_secret(Link *link) {
|
||||
return sysctl_write_ip_property(AF_INET6, link->ifname, "stable_secret", str);
|
||||
}
|
||||
|
||||
int link_set_ipv6ll_addrgen_mode(Link *link, IPv6LinkLocalAddressGenMode mode) {
|
||||
assert(link);
|
||||
assert(mode >= 0 && mode < _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX);
|
||||
|
||||
if (mode == link->ipv6ll_address_gen_mode)
|
||||
return 0;
|
||||
|
||||
return sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "addr_gen_mode", mode);
|
||||
}
|
||||
|
||||
static const char* const ipv6_link_local_address_gen_mode_table[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX] = {
|
||||
[IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64] = "eui64",
|
||||
[IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE] = "none",
|
||||
|
@ -29,6 +29,7 @@ int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalA
|
||||
int link_update_ipv6ll_addrgen_mode(Link *link, sd_netlink_message *message);
|
||||
|
||||
int link_set_ipv6ll_stable_secret(Link *link);
|
||||
int link_set_ipv6ll_addrgen_mode(Link *link, IPv6LinkLocalAddressGenMode mode);
|
||||
|
||||
const char* ipv6_link_local_address_gen_mode_to_string(IPv6LinkLocalAddressGenMode s) _const_;
|
||||
IPv6LinkLocalAddressGenMode ipv6_link_local_address_gen_mode_from_string(const char *s) _pure_;
|
||||
|
@ -688,6 +688,19 @@ int link_request_to_set_addrgen_mode(Link *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)
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user