]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: fix handling of routing policy rule fwmask
authorBeniamino Galvani <b.galvani@gmail.com>
Tue, 15 Apr 2025 20:13:11 +0000 (22:13 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 17 Apr 2025 00:18:54 +0000 (09:18 +0900)
The firewall mask should be applied even if the mark is 0, to allow defining a
value of e.g. 0/255.

Fixes #36973

man/systemd.network.xml
src/network/networkd-routing-policy-rule.c
test/test-network/conf/25-routing-policy-rule-test1.network
test/test-network/systemd-networkd-tests.py

index ba10b7cd9d12225fcb1867f5e7cdd447b4465dae..40aa1b449b36d4311e2f69022e0b032d25a5395c 100644 (file)
@@ -1738,8 +1738,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
         <term><varname>FirewallMark=</varname></term>
         <listitem>
           <para>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 (<literal>/</literal>), e.g., <literal>7/255</literal>.</para>
+          0…4294967295). Optionally, the firewall mask (also a number between 0…4294967295) can be
+          suffixed with a slash (<literal>/</literal>), e.g., <literal>7/255</literal>. When the
+          mark value is non-zero and no mask is explicitly specified, all bits of the mark are
+          compared. </para>
 
           <xi:include href="version-info.xml" xpointer="v235"/>
         </listitem>
index 6c723325cb017a3ce8b4371a3c73070e80586d8f..7c9bd6d0eacb2f51a089415dbd012c0b556f2e53 100644 (file)
@@ -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;
index 6e67f3f105d849a40db574f13dbe7b3f0f565104..66ea59d3a99cc66311c7029263efca96159b8f46 100644 (file)
@@ -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]
index fc7a67c715466b440140fba4d7a2c9bff2a3c7a7..dbc4589aa2d173428326fe515affb9eebf77cc84 100755 (executable)
@@ -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)