diff --git a/man/systemd.network.xml b/man/systemd.network.xml index d23e8a548c..ae93a39eb4 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -672,6 +672,13 @@ When unset, the kernel's default will be used. + + IPv4AcceptLocal= + Takes a boolean. Accept packets with local source addresses. In combination + with suitable routing, this can be used to direct packets between two local interfaces over + the wire and have them accepted properly. When unset, the kernel's default will be used. + + IPv4ProxyARP= Takes a boolean. Configures proxy ARP for IPv4. Proxy ARP is the technique in which one host, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 805aff3ab1..31ffc8b488 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2532,6 +2532,22 @@ static int link_set_ipv6_mtu(Link *link) { return 0; } +static int link_set_ipv4_accept_local(Link *link) { + int r; + + if (link->flags & IFF_LOOPBACK) + return 0; + + if (link->network->ipv4_accept_local < 0) + return 0; + + r = sysctl_write_ip_property_boolean(AF_INET, link->ifname, "accept_local", link->network->ipv4_accept_local); + if (r < 0) + log_link_warning_errno(link, r, "Cannot set IPv4 accept_local flag for interface: %m"); + + return 0; +} + static bool link_is_static_address_configured(Link *link, Address *address) { Address *net_address; @@ -2871,6 +2887,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = link_set_ipv4_accept_local(link); + if (r < 0) + return r; + r = link_set_flags(link); if (r < 0) return r; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 3918890664..5c2a4d36a1 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -96,6 +96,7 @@ Network.IPv6DuplicateAddressDetection, config_parse_int, Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit) Network.IPv6ProxyNDP, config_parse_tristate, 0, offsetof(Network, ipv6_proxy_ndp) Network.IPv6MTUBytes, config_parse_mtu, AF_INET6, offsetof(Network, ipv6_mtu) +Network.IPv4AcceptLocal, config_parse_tristate, 0, offsetof(Network, ipv4_accept_local) Network.ActiveSlave, config_parse_bool, 0, offsetof(Network, active_slave) Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave) Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 124c570b0e..bbecd706ce 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -450,6 +450,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */ .link_local = _ADDRESS_FAMILY_INVALID, + .ipv4_accept_local = -1, + .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO, .ipv6_accept_ra = -1, .ipv6_dad_transmits = -1, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 934a33ac94..5901622862 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -237,6 +237,7 @@ struct Network { AddressFamily ip_forward; bool ip_masquerade; + int ipv4_accept_local; int ipv6_accept_ra; int ipv6_dad_transmits; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 7cade0e9ed..478b574418 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -153,6 +153,7 @@ Address= IPv6ProxyNDPAddress= IPv6AcceptRA= IPv6AcceptRouterAdvertisements= +IPv4AcceptLocal= DNSSECNegativeTrustAnchors= MACVTAP= IPv6PrivacyExtensions= diff --git a/test/test-network/conf/25-sysctl.network b/test/test-network/conf/25-sysctl.network index 68be305477..dc1d6542c0 100644 --- a/test/test-network/conf/25-sysctl.network +++ b/test/test-network/conf/25-sysctl.network @@ -9,3 +9,4 @@ IPv6HopLimit=5 IPv4ProxyARP=true IPv6ProxyNDP=true IPv6AcceptRA=no +IPv4AcceptLocal=yes diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 43730d9f85..5d08a7584c 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2203,6 +2203,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1') self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1') self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1') + self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'accept_local'), '1') def test_sysctl_disable_ipv6(self): copy_unit_to_networkd_unit_path('25-sysctl-disable-ipv6.network', '12-dummy.netdev')