network: unify IPv4ProxyARPAddress= and IPv6ProxyNDPAddress=

It is not necessary to provide dedicated settings for IPv4 and IPv6
proxy neighbor entries. Let's unify them.

The IPv4ProxyARPAddress= setting was introduced after v261. Hence, we
can freely rename it.
This commit is contained in:
Yu Watanabe
2026-08-17 16:58:03 +09:00
parent c1a72ab778
commit 80922ebbc5
6 changed files with 31 additions and 44 deletions
+15 -28
View File
@@ -190,62 +190,49 @@ int config_parse_neighbor_proxy_address(
void *data,
void *userdata) {
_cleanup_free_ struct in_addr_data *address = NULL;
Network *network = ASSERT_PTR(userdata);
int family = ltype;
union in_addr_union buffer = {};
Set **neighbor_proxy_addresses = ASSERT_PTR(data);
int r;
assert(IN_SET(family, AF_INET, AF_INET6));
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
/* Drop only entries belonging to this family, so that
* IPv4ProxyARPAddress= and IPv6ProxyNDPAddress= can be reset independently. */
network_drop_neighbor_proxy_addresses(network, family);
*neighbor_proxy_addresses = set_free(*neighbor_proxy_addresses);
return 0;
}
r = in_addr_from_string(family, rvalue, &buffer);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s, ignoring: %s", lvalue, rvalue);
return 0;
}
struct in_addr_data a = {};
r = in_addr_from_string_auto(rvalue, &a.family, &a.address);
if (r < 0)
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
if (in_addr_is_null(family, &buffer)) {
if (in_addr_is_null(a.family, &a.address)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"%s cannot be the ANY address, ignoring: %s", lvalue, rvalue);
"%s= cannot be the ANY address, ignoring: %s", lvalue, rvalue);
return 0;
}
/* Reject address classes that do not qualify as proxy targets and that the kernel would
* reject: multicast for both families, plus the IPv4 limited broadcast 255.255.255.255. */
if (in_addr_is_multicast(family, &buffer) > 0) {
if (in_addr_is_multicast(a.family, &a.address) > 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"%s cannot be a multicast address, ignoring: %s", lvalue, rvalue);
"%s= cannot be a multicast address, ignoring: %s", lvalue, rvalue);
return 0;
}
if (family == AF_INET && buffer.in.s_addr == htobe32(INADDR_BROADCAST)) {
if (a.family == AF_INET && a.address.in.s_addr == htobe32(INADDR_BROADCAST)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"%s cannot be the limited broadcast address, ignoring: %s",
"%s= cannot be the limited broadcast address, ignoring: %s",
lvalue, rvalue);
return 0;
}
address = new(struct in_addr_data, 1);
if (!address)
struct in_addr_data *copied = newdup(struct in_addr_data, &a, 1);
if (!copied)
return log_oom();
*address = (struct in_addr_data) {
.family = family,
.address = buffer,
};
r = set_ensure_consume(&network->neighbor_proxy_addresses, &in_addr_data_hash_ops_free, TAKE_PTR(address));
r = set_ensure_consume(neighbor_proxy_addresses, &in_addr_data_hash_ops_free, copied);
if (r < 0)
return log_oom();
+2 -2
View File
@@ -176,8 +176,8 @@ Network.PrimarySlave, config_parse_bool,
Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Network.IPv4ProxyARPPrivateVLAN, config_parse_tristate, 0, offsetof(Network, proxy_arp_pvlan)
Network.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Network.IPv4ProxyARPAddress, config_parse_neighbor_proxy_address, AF_INET, 0
Network.IPv6ProxyNDPAddress, config_parse_neighbor_proxy_address, AF_INET6, 0
Network.IPv6ProxyNDPAddress, config_parse_neighbor_proxy_address, 0, offsetof(Network, neighbor_proxy_addresses) /* deprecated */
Network.ProxyNeighbor, config_parse_neighbor_proxy_address, 0, offsetof(Network, neighbor_proxy_addresses)
Network.IPv4ReversePathFilter, config_parse_ip_reverse_path_filter, 0, offsetof(Network, ipv4_rp_filter)
Network.MulticastIGMPVersion, config_parse_ipv4_force_igmp_version, 0, offsetof(Network, ipv4_force_igmp_version)
Network.MPLSRouting, config_parse_tristate, 0, offsetof(Network, mpls_input)
@@ -4,7 +4,7 @@ Name=dummy98
[Network]
IPv4ProxyARP=no
IPv4ProxyARPAddress=192.0.2.1
IPv4ProxyARPAddress=192.0.2.2
ProxyNeighbor=192.0.2.1
ProxyNeighbor=192.0.2.2
IPv6AcceptRA=no
Address=10.0.0.1/24
@@ -3,10 +3,10 @@
Name=dummy98
[Network]
IPv4ProxyARPAddress=192.0.2.1
IPv4ProxyARPAddress=192.0.2.2
IPv4ProxyARPAddress=192.0.2.3
IPv4ProxyARPAddress=192.0.2.4
IPv4ProxyARPAddress=192.0.2.5
ProxyNeighbor=192.0.2.1
ProxyNeighbor=192.0.2.2
ProxyNeighbor=192.0.2.3
ProxyNeighbor=192.0.2.4
ProxyNeighbor=192.0.2.5
IPv6AcceptRA=no
Address=10.0.0.1/24
@@ -3,11 +3,11 @@
Name=dummy98
[Network]
IPv6ProxyNDPAddress=2607:5300:203:5215:5::1
IPv6ProxyNDPAddress=2607:5300:203:5215:4::1
IPv6ProxyNDPAddress=2607:5300:203:5215:3::1
IPv6ProxyNDPAddress=2607:5300:203:5215:2::1
IPv6ProxyNDPAddress=2607:5300:203:5215:1::1
ProxyNeighbor=2607:5300:203:5215:5::1
ProxyNeighbor=2607:5300:203:5215:4::1
ProxyNeighbor=2607:5300:203:5215:3::1
ProxyNeighbor=2607:5300:203:5215:2::1
ProxyNeighbor=2607:5300:203:5215:1::1
IPv6AcceptRA=no
Address=66.70.129.136/32
Address=66.70.129.142/32
+2 -2
View File
@@ -5384,10 +5384,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
for i in range(1, 6):
self.assertRegex(output, f'192.0.2.{i} *proxy')
# IPv4ProxyARPAddress= implies IPv4ProxyARP=yes, mirroring IPv6ProxyNDPAddress=.
# When a proxy ARP address is specified, IPv4ProxyARP=yes is implied.
self.check_ipv4_sysctl_attr('dummy98', 'proxy_arp', '1')
# Explicit IPv4ProxyARP=no must suppress all IPv4ProxyARPAddress= entries and
# Explicit IPv4ProxyARP=no must suppress all IPv4 proxy ARP address entries and
# must not force proxy_arp=1. The module is add-only (no reconcile/remove pass),
# so phase 2 starts from a clean interface: stop networkd, delete the dummy to
# flush the kernel neighbor-proxy table, swap the .network file, and restart.