network: honour static IPv6LL addresses in network_adjust_*()

link_radv_enabled() and link_ndisc_enabled() use
link_ipv6ll_enabled_harder(), which considers a static fe80:: address
in [Address] sufficient to run radv/ndisc even when LinkLocalAddressing=
(or IPv6LinkLocalAddressGenerationMode=none, which network_verify()
folds into the same flag) disables the kernel-generated link-local.

network_adjust_radv()/ndisc()/dhcp() however only check the raw
link_local flag and zero router_prefix_delegation / ndisc / dhcp&IPV6
at parse time, so the runtime gate never gets a chance to fire.

Factor the static-LL lookup out of link_ipv6ll_enabled_harder() into a
Network-level helper and use it in the three network_adjust_*()
functions, bringing parse-time and runtime behaviour in line.
This commit is contained in:
r-vdp
2026-05-15 03:30:01 +09:00
committed by Yu Watanabe
parent a03f3af3e3
commit 39f4185c69
5 changed files with 26 additions and 13 deletions
+2
View File
@@ -19,6 +19,7 @@
#include "iovec-util.h"
#include "networkd-dhcp-common.h"
#include "networkd-dhcp-prefix-delegation.h"
#include "networkd-ipv6ll.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-network.h"
@@ -100,6 +101,7 @@ void network_adjust_dhcp(Network *network) {
}
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6) &&
!network_has_static_ipv6ll_address(network) &&
FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6)) {
log_warning("%s: DHCPv6 client is enabled but IPv6 link-local addressing is disabled. "
"Disabling DHCPv6 client.", network->filename);
+17 -11
View File
@@ -42,6 +42,22 @@ bool link_ipv6ll_enabled(Link *link) {
return link->network->link_local & ADDRESS_FAMILY_IPV6;
}
bool network_has_static_ipv6ll_address(const Network *network) {
assert(network);
Address *a;
ORDERED_HASHMAP_FOREACH(a, 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_ipv6ll_enabled_harder(Link *link) {
assert(link);
@@ -54,17 +70,7 @@ bool link_ipv6ll_enabled_harder(Link *link) {
if (!link->network)
return false;
Address *a;
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;
return network_has_static_ipv6ll_address(link->network);
}
IPv6LinkLocalAddressGenMode link_get_ipv6ll_addrgen_mode(Link *link) {
+1
View File
@@ -16,6 +16,7 @@ typedef enum IPv6LinkLocalAddressGenMode {
bool link_ipv6ll_enabled(Link *link);
bool link_ipv6ll_enabled_harder(Link *link);
bool network_has_static_ipv6ll_address(const Network *network);
IPv6LinkLocalAddressGenMode link_get_ipv6ll_addrgen_mode(Link *link);
int ipv6ll_addrgen_mode_fill_message(sd_netlink_message *message, IPv6LinkLocalAddressGenMode mode);
+3 -1
View File
@@ -17,6 +17,7 @@
#include "networkd-address.h"
#include "networkd-address-generation.h"
#include "networkd-dhcp6.h"
#include "networkd-ipv6ll.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-ndisc.h"
@@ -91,7 +92,8 @@ bool link_ndisc_enabled(Link *link) {
void network_adjust_ndisc(Network *network) {
assert(network);
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6) &&
!network_has_static_ipv6ll_address(network)) {
if (network->ndisc > 0)
log_warning("%s: IPv6AcceptRA= is enabled but IPv6 link-local addressing is disabled or not supported. "
"Disabling IPv6AcceptRA=.", network->filename);
+3 -1
View File
@@ -14,6 +14,7 @@
#include "networkd-address.h"
#include "networkd-address-generation.h"
#include "networkd-dhcp-prefix-delegation.h"
#include "networkd-ipv6ll.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-network.h"
@@ -815,7 +816,8 @@ void network_adjust_radv(Network *network) {
/* For backward compatibility. */
network->dhcp_pd = FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6);
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6) &&
!network_has_static_ipv6ll_address(network)) {
if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE)
log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link-local addressing is disabled. "
"Disabling IPv6PrefixDelegation=.", network->filename);