From: Beniamino Galvani Date: Tue, 15 Apr 2025 20:13:11 +0000 (+0200) Subject: network: fix handling of routing policy rule fwmask X-Git-Tag: v258-rc1~801 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ec65c29e5144bb31abeabed39481c1d149d558ea;p=thirdparty%2Fsystemd.git network: fix handling of routing policy rule fwmask The firewall mask should be applied even if the mark is 0, to allow defining a value of e.g. 0/255. Fixes #36973 --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index ba10b7cd9d1..40aa1b449b3 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1738,8 +1738,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix FirewallMark= Specifies the iptables firewall mark value to match (a number in the range - 1…4294967295). Optionally, the firewall mask (also a number between 1…4294967295) can be - suffixed with a slash (/), e.g., 7/255. + 0…4294967295). Optionally, the firewall mask (also a number between 0…4294967295) can be + suffixed with a slash (/), e.g., 7/255. When the + mark value is non-zero and no mask is explicitly specified, all bits of the mark are + compared. diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 6c723325cb0..7c9bd6d0eac 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -615,7 +615,7 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule if (r < 0) return r; - if (rule->fwmark > 0) { + if (rule->fwmark > 0 || rule->fwmask > 0) { r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark); if (r < 0) return r; @@ -1315,14 +1315,12 @@ static int parse_fwmark_fwmask(const char *s, uint32_t *ret_fwmark, uint32_t *re if (r < 0) return r; - if (fwmark > 0) { - if (slash) { - r = safe_atou32(slash + 1, &fwmask); - if (r < 0) - return r; - } else - fwmask = UINT32_MAX; - } + if (slash) { + r = safe_atou32(slash + 1, &fwmask); + if (r < 0) + return r; + } else if (fwmark > 0) + fwmask = UINT32_MAX; *ret_fwmark = fwmark; *ret_fwmask = fwmask; diff --git a/test/test-network/conf/25-routing-policy-rule-test1.network b/test/test-network/conf/25-routing-policy-rule-test1.network index 6e67f3f105d..66ea59d3a99 100644 --- a/test/test-network/conf/25-routing-policy-rule-test1.network +++ b/test/test-network/conf/25-routing-policy-rule-test1.network @@ -48,6 +48,24 @@ From=10.1.0.0/16 Priority=104 Table=12 +[RoutingPolicyRule] +IncomingInterface=test1 +FirewallMark=0/1 +Priority=200 +Table=20 + +[RoutingPolicyRule] +IncomingInterface=test1 +FirewallMark=7/255 +Priority=201 +Table=21 + +[RoutingPolicyRule] +IncomingInterface=test1 +FirewallMark=9999 +Priority=202 +Table=22 + # The four routing policy rules below intentionally have the same config # excepts for their To= addresses. See issue #35874. [RoutingPolicyRule] diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index fc7a67c7154..dbc4589aa2d 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -3890,6 +3890,18 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): print(output) self.assertIn('104: from 10.1.0.0/16 iif test1 lookup 12 nop', output) + output = check_output('ip rule list iif test1 priority 200') + print(output) + self.assertIn('200: from all fwmark 0/0x1 iif test1 lookup 20', output) + + output = check_output('ip rule list iif test1 priority 201') + print(output) + self.assertIn('201: from all fwmark 0x7/0xff iif test1 lookup 21', output) + + output = check_output('ip rule list iif test1 priority 202') + print(output) + self.assertIn('202: from all fwmark 0x270f iif test1 lookup 22', output) + output = check_output('ip rule list to 192.0.2.0/26') print(output) self.assertIn('to 192.0.2.0/26 lookup 1001', output)