summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-03-22 22:01:08 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-03-23 17:59:38 +0100
commit2859932bd64d61a89f85fa027762bc16961fcf53 (patch)
tree284de37671d1c4793b4b047fe3cd76ca23116936 /src/network
parent000096f4c61477f96fbd9c48b2d772c7c690d259 (diff)
downloadsystemd-2859932bd64d61a89f85fa027762bc16961fcf53.tar.gz
network: do not enable IPv4 ACD for IPv4 link-local address if ACD is disabled explicitly
The commit 1cf4ed142d6c1e2b9dc6a0bc74b6a83ae30b0f8e makes the IPv4 ACD enabled unconditionally for IPv4 link-local addresses even if users explicitly disable ACD. This makes the IPv4 ACD is enabled by default, but honor user setting. Fixes #22763.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-address.c26
-rw-r--r--src/network/networkd-address.h3
2 files changed, 21 insertions, 8 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 19a357130b..eba28cfc67 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -68,7 +68,6 @@ int address_new(Address **ret) {
.lifetime_valid_usec = USEC_INFINITY,
.lifetime_preferred_usec = USEC_INFINITY,
.set_broadcast = -1,
- .duplicate_address_detection = ADDRESS_FAMILY_IPV6,
};
*ret = TAKE_PTR(address);
@@ -106,6 +105,8 @@ static int address_new_static(Network *network, const char *filename, unsigned s
address->network = network;
address->section = TAKE_PTR(n);
address->source = NETWORK_CONFIG_SOURCE_STATIC;
+ /* This will be adjusted in address_section_verify(). */
+ address->duplicate_address_detection = _ADDRESS_FAMILY_INVALID;
r = ordered_hashmap_ensure_put(&network->addresses_by_section, &config_section_hash_ops, address->section, address);
if (r < 0)
@@ -1951,6 +1952,8 @@ static int address_section_verify(Address *address) {
address->section->filename, address->section->line);
}
+ assert(IN_SET(address->family, AF_INET, AF_INET6));
+
if (in4_addr_is_set(&address->broadcast) &&
(address->family == AF_INET6 || address->prefixlen > 30 ||
in_addr_is_set(address->family, &address->in_addr_peer))) {
@@ -1977,17 +1980,24 @@ static int address_section_verify(Address *address) {
address->scope = RT_SCOPE_LINK;
}
+ if (address->duplicate_address_detection < 0) {
+ if (address->family == AF_INET6)
+ address->duplicate_address_detection = ADDRESS_FAMILY_IPV6;
+ else if (in4_addr_is_link_local(&address->in_addr.in))
+ address->duplicate_address_detection = ADDRESS_FAMILY_IPV4;
+ else
+ address->duplicate_address_detection = ADDRESS_FAMILY_NO;
+ } else if (address->duplicate_address_detection == ADDRESS_FAMILY_IPV6 && address->family == AF_INET)
+ log_warning("%s: DuplicateAddressDetection=ipv6 is specified for IPv4 address, ignoring.",
+ address->section->filename);
+ else if (address->duplicate_address_detection == ADDRESS_FAMILY_IPV4 && address->family == AF_INET6)
+ log_warning("%s: DuplicateAddressDetection=ipv4 is specified for IPv6 address, ignoring.",
+ address->section->filename);
+
if (address->family == AF_INET6 &&
!FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV6))
address->flags |= IFA_F_NODAD;
- if (address->family == AF_INET && in4_addr_is_link_local(&address->in_addr.in) &&
- !FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV4)) {
- log_debug("%s: An IPv4 link-local address is specified, enabling IPv4 Address Conflict Detection (ACD).",
- address->section->filename);
- address->duplicate_address_detection |= ADDRESS_FAMILY_IPV4;
- }
-
return 0;
}
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 563a3de4e2..0237c1cb98 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -53,6 +53,9 @@ struct Address {
bool scope_set:1;
bool ip_masquerade_done:1;
+
+ /* duplicate_address_detection is only used by static or IPv4 dynamic addresses.
+ * To control DAD for IPv6 dynamic addresses, set IFA_F_NODAD to flags. */
AddressFamily duplicate_address_detection;
sd_ipv4acd *acd;