diff --git a/src/network/meson.build b/src/network/meson.build index 456599c5d9..35adad42c0 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -93,6 +93,8 @@ sources = files(''' networkd-ipv4ll.h networkd-ipv6-proxy-ndp.c networkd-ipv6-proxy-ndp.h + networkd-ipv6ll.c + networkd-ipv6ll.h networkd-json.c networkd-json.h networkd-link-bus.c diff --git a/src/network/networkd-ipv6ll.c b/src/network/networkd-ipv6ll.c new file mode 100644 index 0000000000..79cf679daf --- /dev/null +++ b/src/network/networkd-ipv6ll.c @@ -0,0 +1,248 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include + +#include "in-addr-util.h" +#include "networkd-address.h" +#include "networkd-ipv6ll.h" +#include "networkd-link.h" +#include "networkd-network.h" +#include "networkd-util.h" +#include "socket-util.h" +#include "string-table.h" +#include "strv.h" +#include "sysctl-util.h" + +bool link_ipv6ll_enabled(Link *link) { + assert(link); + + if (!socket_ipv6_is_supported()) + return false; + + if (link->flags & IFF_LOOPBACK) + return false; + + if (!link->network) + return false; + + if (link->iftype == ARPHRD_CAN) + return false; + + if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "nlmon")) + return false; + + if (link->network->bond) + return false; + + return link->network->link_local & ADDRESS_FAMILY_IPV6; +} + +bool link_may_have_ipv6ll(Link *link) { + assert(link); + + /* + * This is equivalent to link_ipv6ll_enabled() for non-WireGuard interfaces. + * + * For WireGuard interface, the kernel does not assign any IPv6LL addresses, but we can assign + * it manually. It is necessary to set an IPv6LL address manually to run NDisc or RADV on + * WireGuard interface. Note, also Multicast=yes must be set. See #17380. + * + * TODO: May be better to introduce GenerateIPv6LinkLocalAddress= setting, and use algorithms + * used in networkd-address-generation.c + */ + + if (link_ipv6ll_enabled(link)) + return true; + + /* IPv6LL address can be manually assigned on WireGuard interface. */ + if (streq_ptr(link->kind, "wireguard")) { + Address *a; + + if (!link->network) + return false; + + ORDERED_HASHMAP_FOREACH(a, link->network->addresses_by_section) { + if (a->family != AF_INET6) + continue; + if (in6_addr_is_set(&a->in_addr_peer.in6)) + continue; + if (in6_addr_is_link_local(&a->in_addr.in6)) + return true; + } + } + + return false; +} + +IPv6LinkLocalAddressGenMode link_get_ipv6ll_addrgen_mode(Link *link) { + assert(link); + + if (!link_ipv6ll_enabled(link)) + return IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE; + + if (link->network->ipv6ll_address_gen_mode >= 0) + return link->network->ipv6ll_address_gen_mode; + + if (in6_addr_is_set(&link->network->ipv6ll_stable_secret)) + return IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY; + + return IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64; +} + +int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalAddressGenMode mode) { + int r; + + assert(message); + assert(mode >= 0 && mode < _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX); + + r = sd_netlink_message_open_container(message, IFLA_AF_SPEC); + if (r < 0) + return r; + + r = sd_netlink_message_open_container(message, AF_INET6); + if (r < 0) + return r; + + r = sd_netlink_message_append_u8(message, IFLA_INET6_ADDR_GEN_MODE, mode); + if (r < 0) + return r; + + r = sd_netlink_message_close_container(message); + if (r < 0) + return r; + + r = sd_netlink_message_close_container(message); + if (r < 0) + return r; + + return 0; +} + +int link_update_ipv6ll_addrgen_mode(Link *link, sd_netlink_message *message) { + uint8_t mode; + int family, r; + + assert(link); + assert(message); + + r = sd_rtnl_message_get_family(message, &family); + if (r < 0) + return r; + + if (family != AF_UNSPEC) + return 0; + + r = sd_netlink_message_enter_container(message, IFLA_AF_SPEC); + if (r == -ENODATA) + return 0; + if (r < 0) + return r; + + r = sd_netlink_message_enter_container(message, AF_INET6); + if (r == -ENODATA) + return sd_netlink_message_exit_container(message); + if (r < 0) + return r; + + mode = (uint8_t) link->ipv6ll_address_gen_mode; + r = sd_netlink_message_read_u8(message, IFLA_INET6_ADDR_GEN_MODE, &mode); + if (r < 0 && r != -ENODATA) + return r; + + r = sd_netlink_message_exit_container(message); + if (r < 0) + return r; + + r = sd_netlink_message_exit_container(message); + if (r < 0) + return r; + + if (mode == (uint8_t) link->ipv6ll_address_gen_mode) + return 0; + + if (mode >= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX) { + log_link_debug(link, "Received invalid IPv6 link-local address generation mode (%u), ignoring.", mode); + return 0; + } + + if (link->ipv6ll_address_gen_mode < 0) + log_link_debug(link, "Saved IPv6 link-local address generation mode: %s", + ipv6_link_local_address_gen_mode_to_string(mode)); + else + log_link_debug(link, "IPv6 link-local address generation mode is changed: %s -> %s", + ipv6_link_local_address_gen_mode_to_string(link->ipv6ll_address_gen_mode), + ipv6_link_local_address_gen_mode_to_string(mode)); + + link->ipv6ll_address_gen_mode = mode; + return 0; +} + +#define STABLE_SECRET_APP_ID_1 SD_ID128_MAKE(aa,05,1d,94,43,68,45,07,b9,73,f1,e8,e4,b7,34,52) +#define STABLE_SECRET_APP_ID_2 SD_ID128_MAKE(52,c4,40,a0,9f,2f,48,58,a9,3a,f6,29,25,ba,7a,7d) + +int link_set_ipv6ll_stable_secret(Link *link) { + _cleanup_free_ char *str = NULL; + struct in6_addr a; + int r; + + assert(link); + assert(link->network); + + if (link->network->ipv6ll_address_gen_mode != IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY) + return 0; + + if (in6_addr_is_set(&link->network->ipv6ll_stable_secret)) + a = link->network->ipv6ll_stable_secret; + else { + sd_id128_t key; + le64_t v; + + /* Generate a stable secret address from machine-ID and the interface name. */ + + r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_1, &key); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to generate key: %m"); + + v = htole64(siphash24_string(link->ifname, key.bytes)); + memcpy(a.s6_addr, &v, sizeof(v)); + + r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_2, &key); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to generate key: %m"); + + v = htole64(siphash24_string(link->ifname, key.bytes)); + assert_cc(sizeof(v) * 2 == sizeof(a.s6_addr)); + memcpy(a.s6_addr + sizeof(v), &v, sizeof(v)); + } + + r = in6_addr_to_string(&a, &str); + if (r < 0) + return r; + + 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", + [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY] = "stable-privacy", + [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM] = "random", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode); +DEFINE_CONFIG_PARSE_ENUM( + config_parse_ipv6_link_local_address_gen_mode, + ipv6_link_local_address_gen_mode, + IPv6LinkLocalAddressGenMode, + "Failed to parse IPv6 link local address generation mode"); diff --git a/src/network/networkd-ipv6ll.h b/src/network/networkd-ipv6ll.h new file mode 100644 index 0000000000..a9763debb1 --- /dev/null +++ b/src/network/networkd-ipv6ll.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "sd-netlink.h" + +#include "conf-parser.h" +#include "macro.h" + +typedef struct Link Link; + +typedef enum IPv6LinkLocalAddressGenMode { + IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64 = IN6_ADDR_GEN_MODE_EUI64, + IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE = IN6_ADDR_GEN_MODE_NONE, + IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY = IN6_ADDR_GEN_MODE_STABLE_PRIVACY, + IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM = IN6_ADDR_GEN_MODE_RANDOM, + _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX, + _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID = -EINVAL, +} IPv6LinkLocalAddressGenMode; + +bool link_ipv6ll_enabled(Link *link); +bool link_may_have_ipv6ll(Link *link); + +IPv6LinkLocalAddressGenMode link_get_ipv6ll_addrgen_mode(Link *link); +int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalAddressGenMode mode); +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_; + +CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 43372caa35..de21343854 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -105,67 +105,6 @@ bool link_ipv4ll_enabled(Link *link) { return link->network->link_local & ADDRESS_FAMILY_IPV4; } -bool link_ipv6ll_enabled(Link *link) { - assert(link); - - if (!socket_ipv6_is_supported()) - return false; - - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - if (link->iftype == ARPHRD_CAN) - return false; - - if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "nlmon")) - return false; - - if (link->network->bond) - return false; - - return link->network->link_local & ADDRESS_FAMILY_IPV6; -} - -bool link_may_have_ipv6ll(Link *link) { - assert(link); - - /* - * This is equivalent to link_ipv6ll_enabled() for non-WireGuard interfaces. - * - * For WireGuard interface, the kernel does not assign any IPv6LL addresses, but we can assign - * it manually. It is necessary to set an IPv6LL address manually to run NDisc or RADV on - * WireGuard interface. Note, also Multicast=yes must be set. See #17380. - * - * TODO: May be better to introduce GenerateIPv6LinkLocalAddress= setting, and use algorithms - * used in networkd-address-generation.c - */ - - if (link_ipv6ll_enabled(link)) - return true; - - /* IPv6LL address can be manually assigned on WireGuard interface. */ - if (streq_ptr(link->kind, "wireguard")) { - Address *a; - - if (!link->network) - return false; - - ORDERED_HASHMAP_FOREACH(a, link->network->addresses_by_section) { - if (a->family != AF_INET6) - continue; - if (in6_addr_is_set(&a->in_addr_peer.in6)) - continue; - if (in6_addr_is_link_local(&a->in_addr.in6)) - return true; - } - } - - return false; -} - bool link_ipv6_enabled(Link *link) { assert(link); @@ -2377,6 +2316,10 @@ static int link_update(Link *link, sd_netlink_message *message) { if (r < 0) return r; + r = link_update_ipv6ll_addrgen_mode(link, message); + if (r < 0) + return r; + return link_update_flags(link, message); } @@ -2450,6 +2393,8 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { .ifname = TAKE_PTR(ifname), .kind = TAKE_PTR(kind), + .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID, + .state_file = TAKE_PTR(state_file), .lease_file = TAKE_PTR(lease_file), .lldp_file = TAKE_PTR(lldp_file), @@ -2569,7 +2514,7 @@ int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Man /* netdev exists, so make sure the ifindex matches */ r = netdev_set_ifindex(netdev, message); if (r < 0) { - log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m"); + log_netdev_warning_errno(netdev, r, "Could not process new link message for netdev, ignoring: %m"); return 0; } } @@ -2584,32 +2529,30 @@ int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Man r = link_update(link, message); if (r < 0) { - log_warning_errno(r, "Could not process link message: %m"); + log_link_warning_errno(link, r, "Could not process link message: %m"); link_enter_failed(link); return 0; } r = link_check_initialized(link); if (r < 0) { - log_warning_errno(r, "Failed to check link is initialized: %m"); + log_link_warning_errno(link, r, "Failed to check link is initialized: %m"); link_enter_failed(link); return 0; } } else { r = link_update(link, message); if (r < 0) { - log_warning_errno(r, "Could not process link message: %m"); + log_link_warning_errno(link, r, "Could not process link message: %m"); link_enter_failed(link); return 0; } } - break; case RTM_DELLINK: link_drop(link); netdev_drop(netdev); - break; default: diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 23a893449f..0b257c2414 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -21,6 +21,7 @@ #include "log-link.h" #include "netif-util.h" #include "network-util.h" +#include "networkd-ipv6ll.h" #include "networkd-util.h" #include "ordered-set.h" #include "resolve-util.h" @@ -67,6 +68,9 @@ typedef struct Link { sd_device *sd_device; char *driver; + /* link local addressing */ + IPv6LinkLocalAddressGenMode ipv6ll_address_gen_mode; + /* wlan */ enum nl80211_iftype wlan_iftype; char *ssid; @@ -220,8 +224,6 @@ static inline bool link_has_carrier(Link *link) { } bool link_ipv6_enabled(Link *link); -bool link_ipv6ll_enabled(Link *link); -bool link_may_have_ipv6ll(Link *link); int link_ipv6ll_gained(Link *link); bool link_ipv4ll_enabled(Link *link); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c2ea2d681f..c3de7d7239 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -22,6 +22,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "networkd-dhcp6.h" #include "networkd-ipv4ll.h" #include "networkd-ipv6-proxy-ndp.h" +#include "networkd-ipv6ll.h" #include "networkd-lldp-tx.h" #include "networkd-ndisc.h" #include "networkd-network.h" diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 24ea5f605e..a2c6825439 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1386,16 +1386,6 @@ static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = { DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES); -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", - [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY] = "stable-privacy", - [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM] = "random", -}; - -DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode, ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode, "Failed to parse IPv6 link local address generation mode"); - static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = { [ACTIVATION_POLICY_UP] = "up", [ACTIVATION_POLICY_ALWAYS_UP] = "always-up", diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 1456cc12ef..47248f790b 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -18,6 +18,7 @@ #include "networkd-dhcp-common.h" #include "networkd-dhcp4.h" #include "networkd-dhcp6.h" +#include "networkd-ipv6ll.h" #include "networkd-lldp-rx.h" #include "networkd-ndisc.h" #include "networkd-radv.h" @@ -38,15 +39,6 @@ typedef enum KeepConfiguration { _KEEP_CONFIGURATION_INVALID = -EINVAL, } KeepConfiguration; -typedef enum IPv6LinkLocalAddressGenMode { - IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64 = IN6_ADDR_GEN_MODE_EUI64, - IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE = IN6_ADDR_GEN_MODE_NONE, - IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY = IN6_ADDR_GEN_MODE_STABLE_PRIVACY, - IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM = IN6_ADDR_GEN_MODE_RANDOM, - _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX, - _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID = -EINVAL, -} IPv6LinkLocalAddressGenMode; - typedef enum ActivationPolicy { ACTIVATION_POLICY_UP, ACTIVATION_POLICY_ALWAYS_UP, @@ -386,7 +378,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online); CONFIG_PARSER_PROTOTYPE(config_parse_required_family_for_online); CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration); -CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode); CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy); CONFIG_PARSER_PROTOTYPE(config_parse_link_group); CONFIG_PARSER_PROTOTYPE(config_parse_ignore_carrier_loss); @@ -396,8 +387,5 @@ const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF const char* keep_configuration_to_string(KeepConfiguration i) _const_; KeepConfiguration keep_configuration_from_string(const char *s) _pure_; -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_; - const char* activation_policy_to_string(ActivationPolicy i) _const_; ActivationPolicy activation_policy_from_string(const char *s) _pure_; 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) diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 6c7a606dfb..4e4b285f08 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -11,9 +11,6 @@ #include "string-table.h" #include "sysctl-util.h" -#define STABLE_SECRET_APP_ID_1 SD_ID128_MAKE(aa,05,1d,94,43,68,45,07,b9,73,f1,e8,e4,b7,34,52) -#define STABLE_SECRET_APP_ID_2 SD_ID128_MAKE(52,c4,40,a0,9f,2f,48,58,a9,3a,f6,29,25,ba,7a,7d) - static int link_update_ipv6_sysctl(Link *link) { assert(link); @@ -214,48 +211,6 @@ int link_set_ipv6_mtu(Link *link) { return sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", mtu); } -static int link_set_ipv6ll_stable_secret(Link *link) { - _cleanup_free_ char *str = NULL; - struct in6_addr a; - int r; - - assert(link); - assert(link->network); - - if (link->network->ipv6ll_address_gen_mode != IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY) - return 0; - - if (in6_addr_is_set(&link->network->ipv6ll_stable_secret)) - a = link->network->ipv6ll_stable_secret; - else { - sd_id128_t key; - le64_t v; - - /* Generate a stable secret address from machine-ID and the interface name. */ - - r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_1, &key); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to generate key: %m"); - - v = htole64(siphash24_string(link->ifname, key.bytes)); - memcpy(a.s6_addr, &v, sizeof(v)); - - r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_2, &key); - if (r < 0) - return log_link_debug_errno(link, r, "Failed to generate key: %m"); - - v = htole64(siphash24_string(link->ifname, key.bytes)); - assert_cc(sizeof(v) * 2 == sizeof(a.s6_addr)); - memcpy(a.s6_addr + sizeof(v), &v, sizeof(v)); - } - - r = in6_addr_to_string(&a, &str); - if (r < 0) - return r; - - return sysctl_write_ip_property(AF_INET6, link->ifname, "stable_secret", str); -} - static int link_set_ipv4_accept_local(Link *link) { assert(link); diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 4f96bca33e..e3fd85d4f2 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2952,22 +2952,35 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertEqual(read_ipv6_sysctl_attr('test1', 'addr_gen_mode'), '2') self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'addr_gen_mode'), '1') - def test_link_local_addressing_remove_ipv6ll(self): + def test_link_local_addressing_ipv6ll(self): copy_unit_to_networkd_unit_path('26-link-local-addressing-ipv6.network', '12-dummy.netdev') start_networkd() self.wait_online(['dummy98:degraded']) + # An IPv6LL address exists by default. output = check_output('ip address show dev dummy98') print(output) self.assertRegex(output, 'inet6 .* scope link') copy_unit_to_networkd_unit_path('25-link-local-addressing-no.network') - restart_networkd(1) + check_output(*networkctl_cmd, 'reload', env=env) + time.sleep(1) self.wait_online(['dummy98:carrier']) + # Check if the IPv6LL address is removed. output = check_output('ip address show dev dummy98') print(output) - self.assertNotRegex(output, 'inet6* .* scope link') + self.assertNotRegex(output, 'inet6 .* scope link') + + remove_unit_from_networkd_path(['25-link-local-addressing-no.network']) + check_output(*networkctl_cmd, 'reload', env=env) + time.sleep(1) + self.wait_online(['dummy98:degraded']) + + # Check if a new IPv6LL address is assigned. + output = check_output('ip address show dev dummy98') + print(output) + self.assertRegex(output, 'inet6 .* scope link') def test_sysctl(self): copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')