]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
mergesort: Fix sorting of string values
authorPhil Sutter <phil@nwl.cc>
Wed, 12 Nov 2025 23:03:37 +0000 (00:03 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 27 Jan 2026 22:01:54 +0000 (23:01 +0100)
Sorting order was obviously wrong, e.g. "ppp0" ordered before "eth1".
Moreover, this happened on Little Endian only so sorting order actually
depended on host's byteorder. By reimporting string values as Big
Endian, both issues are fixed: On one hand, GMP-internal byteorder no
longer depends on host's byteorder, on the other comparing strings
really starts with the first character, not the last.

Fixes: 14ee0a979b622 ("src: sort set elements in netlink_get_setelems()")
Signed-off-by: Phil Sutter <phil@nwl.cc>
src/mergesort.c
tests/py/any/meta.t.json.output
tests/py/any/queue.t.json.output
tests/py/inet/osf.t.json.output
tests/shell/testcases/maps/dumps/0012map_0.json-nft
tests/shell/testcases/maps/dumps/0012map_0.nft
tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
tests/shell/testcases/maps/dumps/named_ct_objects.nft
tests/shell/testcases/sets/dumps/sets_with_ifnames.json-nft
tests/shell/testcases/sets/dumps/sets_with_ifnames.nft

index a9cba614612ed4cba44815eba4da3a18a2b6e81d..97e36917280f308e1e3aced2d55b91714a3eb008 100644 (file)
@@ -37,6 +37,13 @@ static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
        case EXPR_RANGE:
                return expr_msort_value(expr->left, value);
        case EXPR_VALUE:
+               if (expr_basetype(expr)->type == TYPE_STRING) {
+                       char buf[expr->len];
+
+                       mpz_export_data(buf, expr->value, BYTEORDER_HOST_ENDIAN, expr->len);
+                       mpz_import_data(value, buf, BYTEORDER_BIG_ENDIAN, expr->len);
+                       return value;
+               }
                return expr->value;
        case EXPR_RANGE_VALUE:
                return expr->range.low;
index 8f4d597a5034eb54ad33fbca1dcffa45c0524f79..4454bb960385d5b7375107c464570c8454891bf6 100644 (file)
     }
 ]
 
-# meta iifname {"dummy0", "lo"}
-[
-    {
-        "match": {
-            "left": {
-                "meta": { "key": "iifname" }
-            },
-           "op": "==",
-            "right": {
-                "set": [
-                    "lo",
-                    "dummy0"
-                ]
-            }
-        }
-    }
-]
-
-# meta iifname != {"dummy0", "lo"}
-[
-    {
-        "match": {
-            "left": {
-                "meta": { "key": "iifname" }
-            },
-            "op": "!=",
-            "right": {
-                "set": [
-                    "lo",
-                    "dummy0"
-                ]
-            }
-        }
-    }
-]
-
-# meta oifname { "dummy0", "lo"}
-[
-    {
-        "match": {
-            "left": {
-                "meta": { "key": "oifname" }
-            },
-           "op": "==",
-            "right": {
-                "set": [
-                    "lo",
-                    "dummy0"
-                ]
-            }
-        }
-    }
-]
-
 # meta skuid {"bin", "root", "daemon"} accept
 [
     {
index ea3722383f113a5eafa2a2a71eff3a999a0406ed..90670cc93886639c772e19fcab9d4067950be705 100644 (file)
                                 0
                             ],
                             [
-                                "ppp0",
+                                "eth1",
                                 2
                             ],
                             [
-                                "eth1",
+                                "ppp0",
                                 2
                             ]
                         ]
index 922e395f202c71a54e00eb6cd4d251bf084d4893..77ca7e30e0f77a93ccc0d3d443f4b6af3783fb4d 100644 (file)
     }
 ]
 
+# osf version { "Windows:XP", "MacOs:Sierra" }
+[
+    {
+        "match": {
+            "left": {
+                "osf": {
+                    "key": "version"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    "MacOs:Sierra",
+                    "Windows:XP"
+                ]
+            }
+        }
+    }
+]
+
 # ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
 [
     {
         }
     }
 ]
+
+# ct mark set osf version map { "Windows:XP" : 0x00000003, "MacOs:Sierra" : 0x00000004 }
+[
+    {
+        "mangle": {
+            "key": {
+                "ct": {
+                    "key": "mark"
+                }
+            },
+            "value": {
+                "map": {
+                    "data": {
+                        "set": [
+                            [
+                                "MacOs:Sierra",
+                                4
+                            ],
+                            [
+                                "Windows:XP",
+                                3
+                            ]
+                        ]
+                    },
+                    "key": {
+                        "osf": {
+                            "key": "version"
+                        }
+                    }
+                }
+            }
+        }
+    }
+]
index 2892e11d71f541dff2c0b290d62dc34e7f9675df..6c885703ffd6b151047853ccb628826fa1083b09 100644 (file)
         "map": "verdict",
         "elem": [
           [
-            "lo",
+            "eth0",
             {
-              "accept": null
+              "drop": null
             }
           ],
           [
-            "eth0",
+            "eth1",
             {
               "drop": null
             }
           ],
           [
-            "eth1",
+            "lo",
             {
-              "drop": null
+              "accept": null
             }
           ]
         ]
               "data": {
                 "set": [
                   [
-                    "lo",
+                    "eth0",
                     {
-                      "accept": null
+                      "drop": null
                     }
                   ],
                   [
-                    "eth0",
+                    "eth1",
                     {
                       "drop": null
                     }
                   ],
                   [
-                    "eth1",
+                    "lo",
                     {
-                      "drop": null
+                      "accept": null
                     }
                   ]
                 ]
index e734fc1c70b9383d436c91abb5c95a0139eaebe4..0df329a55051890171a65591b8c79ec090083f32 100644 (file)
@@ -1,12 +1,12 @@
 table ip x {
        map z {
                type ifname : verdict
-               elements = { "lo" : accept,
-                            "eth0" : drop,
-                            "eth1" : drop }
+               elements = { "eth0" : drop,
+                            "eth1" : drop,
+                            "lo" : accept }
        }
 
        chain y {
-               iifname vmap { "lo" : accept, "eth0" : drop, "eth1" : drop }
+               iifname vmap { "eth0" : drop, "eth1" : drop, "lo" : accept }
        }
 }
index c0f270e372b2462b451c4298e57f4832566e1cf7..34c8798dee8fbf106615821501bf37697a1bf33f 100644 (file)
         },
         "handle": 0,
         "elem": [
-          "sip",
-          "ftp"
+          "ftp",
+          "sip"
         ]
       }
     },
index 59f18932b28add96fc71d5023ab73ca136619080..dab683bf5cdbdbcc595ec15556acba52b7fc8cb3 100644 (file)
@@ -50,8 +50,8 @@ table inet t {
 
        set helpname {
                typeof ct helper
-               elements = { "sip",
-                            "ftp" }
+               elements = { "ftp",
+                            "sip" }
        }
 
        chain y {
index ac4284293c32ab492b7aab112c8b23eda5cbe564..7b4849e0530d3c2c95e24a74e5929b27399b68b7 100644 (file)
               },
               "right": {
                 "set": [
-                  "eth0",
-                  "abcdef0"
+                  "abcdef0",
+                  "eth0"
                 ]
               }
             }
index 77a8baf58cef26a89ca77cc34a9bd580265222b6..8abca03a080ec722a7fb4b4016f5af1819315e7e 100644 (file)
@@ -39,7 +39,7 @@ table inet testifsets {
        chain v4icmp {
                iifname @simple counter packets 0 bytes 0
                iifname @simple_wild counter packets 0 bytes 0
-               iifname { "eth0", "abcdef0" } counter packets 0 bytes 0
+               iifname { "abcdef0", "eth0" } counter packets 0 bytes 0
                iifname { "abcdef*", "eth0" } counter packets 0 bytes 0
                iifname vmap @map_wild
        }