From 1fcb88b234147210069469bb6a14f836377d15e1 Mon Sep 17 00:00:00 2001 From: ssahani Date: Fri, 27 Mar 2026 09:19:44 +0530 Subject: [PATCH 1/2] networkd: Add IPv4SrcValidMark= support Add support for configuring net.ipv4.conf..src_valid_mark via the [Network] section in .network files. Co-developed-by: Claude Opus 4.6 --- src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + src/network/networkd-sysctl.c | 17 +++++++++++++++++ 4 files changed, 20 insertions(+) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index f1049cc7cc..aaf974e312 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -168,6 +168,7 @@ Network.IPv6ProxyNDP, config_parse_tristate, Network.IPv6MTUBytes, config_parse_mtu, AF_INET6, offsetof(Network, ipv6_mtu) Network.IPv4AcceptLocal, config_parse_tristate, 0, offsetof(Network, ipv4_accept_local) Network.IPv4RouteLocalnet, config_parse_tristate, 0, offsetof(Network, ipv4_route_localnet) +Network.IPv4SrcValidMark, config_parse_tristate, 0, offsetof(Network, ipv4_src_valid_mark) 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 1e159fa310..3ffe1640e7 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -479,6 +479,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .ip_forwarding = { -1, -1, }, .ipv4_accept_local = -1, .ipv4_route_localnet = -1, + .ipv4_src_valid_mark = -1, .ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID, .ipv6_dad_transmits = -1, .ipv6_proxy_ndp = -1, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 923828b2ea..9a36c312f8 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -332,6 +332,7 @@ typedef struct Network { int ip_forwarding[2]; int ipv4_accept_local; int ipv4_route_localnet; + int ipv4_src_valid_mark; int ipv6_dad_transmits; uint8_t ipv6_hop_limit; usec_t ipv6_retransmission_time; diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 914fbccd09..8946f36960 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -662,6 +662,19 @@ static int link_set_ipv4_route_localnet(Link *link) { return sysctl_write_ip_property_boolean(AF_INET, link->ifname, "route_localnet", link->network->ipv4_route_localnet > 0, manager_get_sysctl_shadow(link->manager)); } +static int link_set_ipv4_src_valid_mark(Link *link) { + assert(link); + assert(link->manager); + + if (!link_is_configured_for_family(link, AF_INET)) + return 0; + + if (link->network->ipv4_src_valid_mark < 0) + return 0; + + return sysctl_write_ip_property_boolean(AF_INET, link->ifname, "src_valid_mark", link->network->ipv4_src_valid_mark > 0, manager_get_sysctl_shadow(link->manager)); +} + static int link_set_ipv4_promote_secondaries(Link *link) { assert(link); assert(link->manager); @@ -750,6 +763,10 @@ int link_set_sysctl(Link *link) { if (r < 0) log_link_warning_errno(link, r, "Cannot set IPv4 route_localnet flag for interface, ignoring: %m"); + r = link_set_ipv4_src_valid_mark(link); + if (r < 0) + log_link_warning_errno(link, r, "Cannot set IPv4 src_valid_mark flag for interface, ignoring: %m"); + r = link_set_ipv4_rp_filter(link); if (r < 0) log_link_warning_errno(link, r, "Cannot set IPv4 reverse path filtering for interface, ignoring: %m"); From 2f69c8e712a31f9b99019b602bebe0c7dc82c41b Mon Sep 17 00:00:00 2001 From: ssahani Date: Fri, 27 Mar 2026 09:19:49 +0530 Subject: [PATCH 2/2] networkd: Add docs and tests for IPv4SrcValidMark= Document the new setting in systemd.network(5) man page and add coverage in the networkd integration tests. Co-developed-by: Claude Opus 4.6 --- man/systemd.network.xml | 13 +++++++++++++ src/network/networkd-sysctl.c | 1 + test/test-network/conf/25-sysctl.network | 1 + test/test-network/systemd-networkd-tests.py | 1 + 4 files changed, 16 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 4c777ef4e0..554d8da8ef 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1086,6 +1086,19 @@ DuplicateAddressDetection=none + + IPv4SrcValidMark= + + Takes a boolean. When enabled, the packet's firewall mark (fwmark) is included in the + reverse path filter route lookup for source address validation on this interface. This is + particularly useful for policy routing setups where packets may arrive with source addresses + that are only valid in routing tables selected by their fwmark. When unset, the kernel's + default will be used. + + + + + IPv4ProxyARP= diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 8946f36960..e5f5c07ff1 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -665,6 +665,7 @@ static int link_set_ipv4_route_localnet(Link *link) { static int link_set_ipv4_src_valid_mark(Link *link) { assert(link); assert(link->manager); + assert(link->network); if (!link_is_configured_for_family(link, AF_INET)) return 0; diff --git a/test/test-network/conf/25-sysctl.network b/test/test-network/conf/25-sysctl.network index dcc4f0d293..c0c709c32c 100644 --- a/test/test-network/conf/25-sysctl.network +++ b/test/test-network/conf/25-sysctl.network @@ -12,5 +12,6 @@ IPv4ProxyARPPrivateVLAN=yes IPv6ProxyNDP=yes IPv6AcceptRA=no IPv4AcceptLocal=yes +IPv4SrcValidMark=yes IPv4ReversePathFilter=no MulticastIGMPVersion=v1 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index bab725bd23..38443315e6 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -4972,6 +4972,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.check_ipv4_sysctl_attr('dummy98', 'proxy_arp', '1') self.check_ipv4_sysctl_attr('dummy98', 'proxy_arp_pvlan', '1') self.check_ipv4_sysctl_attr('dummy98', 'accept_local', '1') + self.check_ipv4_sysctl_attr('dummy98', 'src_valid_mark', '1') self.check_ipv4_sysctl_attr('dummy98', 'rp_filter', '0') self.check_ipv4_sysctl_attr('dummy98', 'force_igmp_version', '1')