* Thu Nov 27 2025 Phil Sutter <psutter@redhat.com> [1.1.5-2.el10] - spec: Require libnftnl >= 1.3.0-2 for NFTA_DEVICE_PREFIX handling (Phil Sutter) [RHEL-108861] - mnl: Drop asterisk from end of NFTA_DEVICE_PREFIX strings (Phil Sutter) [RHEL-108861] - tests: shell: Test ifname-based hooks (Phil Sutter) [RHEL-108861] - parser_bison: Accept ASTERISK_STRING in flowtable_expr_member (Phil Sutter) [RHEL-108861] - mnl: Support simple wildcards in netdev hooks (Phil Sutter) [RHEL-108861] Resolves: RHEL-108861
258 lines
7.9 KiB
Diff
258 lines
7.9 KiB
Diff
From 22b7438f93073a76836a571b42e78df7638e117e Mon Sep 17 00:00:00 2001
|
|
From: Phil Sutter <psutter@redhat.com>
|
|
Date: Thu, 27 Nov 2025 10:58:08 +0100
|
|
Subject: [PATCH] tests: shell: Test ifname-based hooks
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-108861
|
|
Upstream Status: nftables commit 12c31bc2a822437d026b0cd83143d45808971404
|
|
|
|
commit 12c31bc2a822437d026b0cd83143d45808971404
|
|
Author: Phil Sutter <phil@nwl.cc>
|
|
Date: Tue Jul 15 15:26:33 2025 +0200
|
|
|
|
tests: shell: Test ifname-based hooks
|
|
|
|
Assert that:
|
|
- Non-matching interface specs are accepted
|
|
- Existing interfaces are hooked into upon flowtable/chain creation
|
|
- A new device matching the spec is hooked into immediately
|
|
- No stale hooks remain in 'nft list hooks' output
|
|
- Wildcard hooks basically work
|
|
|
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
---
|
|
.../features/list_hooks_flowtable_info.sh | 7 +++
|
|
.../netdev_chain_name_based_hook_0.json-nft | 34 ++++++++++++++
|
|
.../dumps/netdev_chain_name_based_hook_0.nft | 5 +++
|
|
.../chains/netdev_chain_name_based_hook_0 | 44 ++++++++++++++++++
|
|
.../testcases/flowtable/0016name_based_hook_0 | 45 +++++++++++++++++++
|
|
.../dumps/0016name_based_hook_0.json-nft | 32 +++++++++++++
|
|
.../flowtable/dumps/0016name_based_hook_0.nft | 6 +++
|
|
7 files changed, 173 insertions(+)
|
|
create mode 100755 tests/shell/features/list_hooks_flowtable_info.sh
|
|
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
|
|
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
|
|
create mode 100755 tests/shell/testcases/chains/netdev_chain_name_based_hook_0
|
|
create mode 100755 tests/shell/testcases/flowtable/0016name_based_hook_0
|
|
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
|
|
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
|
|
|
|
diff --git a/tests/shell/features/list_hooks_flowtable_info.sh b/tests/shell/features/list_hooks_flowtable_info.sh
|
|
new file mode 100755
|
|
index 0000000..58bc57e
|
|
--- /dev/null
|
|
+++ b/tests/shell/features/list_hooks_flowtable_info.sh
|
|
@@ -0,0 +1,7 @@
|
|
+#!/bin/sh
|
|
+
|
|
+# check for flowtable info in 'list hooks' output
|
|
+
|
|
+unshare -n bash -c " \
|
|
+$NFT \"table inet t { flowtable ft { hook ingress priority 0; devices = { lo }; }; }\"; \
|
|
+$NFT list hooks netdev device lo | grep -q flowtable\ inet\ t\ ft"
|
|
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
|
|
new file mode 100644
|
|
index 0000000..0070627
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
|
|
@@ -0,0 +1,34 @@
|
|
+{
|
|
+ "nftables": [
|
|
+ {
|
|
+ "metainfo": {
|
|
+ "version": "VERSION",
|
|
+ "release_name": "RELEASE_NAME",
|
|
+ "json_schema_version": 1
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "table": {
|
|
+ "family": "netdev",
|
|
+ "name": "t",
|
|
+ "handle": 0
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "chain": {
|
|
+ "family": "netdev",
|
|
+ "table": "t",
|
|
+ "name": "c",
|
|
+ "handle": 0,
|
|
+ "dev": [
|
|
+ "foo*",
|
|
+ "lo"
|
|
+ ],
|
|
+ "type": "filter",
|
|
+ "hook": "ingress",
|
|
+ "prio": 0,
|
|
+ "policy": "accept"
|
|
+ }
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
|
|
new file mode 100644
|
|
index 0000000..ac5acac
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
|
|
@@ -0,0 +1,5 @@
|
|
+table netdev t {
|
|
+ chain c {
|
|
+ type filter hook ingress devices = { "foo*", "lo" } priority filter; policy accept;
|
|
+ }
|
|
+}
|
|
diff --git a/tests/shell/testcases/chains/netdev_chain_name_based_hook_0 b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
|
|
new file mode 100755
|
|
index 0000000..8a8a601
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
|
|
@@ -0,0 +1,44 @@
|
|
+#!/bin/bash
|
|
+
|
|
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
|
|
+
|
|
+cspec=' chain netdev t c '
|
|
+$NFT add table netdev t
|
|
+$NFT add $cspec '{ type filter hook ingress priority 0; devices = { lo, foo* }; }'
|
|
+$NFT list hooks netdev device lo | grep -q "$cspec" || {
|
|
+ echo "Existing device lo not hooked into chain as expected"
|
|
+ exit 1
|
|
+}
|
|
+
|
|
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
|
|
+ echo "Chain hooks into more than just lo"
|
|
+ exit 2
|
|
+}
|
|
+
|
|
+ip link add foo1 type dummy
|
|
+$NFT list hooks netdev device foo1 | grep -q "$cspec" || {
|
|
+ echo "Chain did not hook into new device foo1"
|
|
+ exit 3
|
|
+}
|
|
+[[ $($NFT list hooks | grep -c "$cspec") -eq 2 ]] || {
|
|
+ echo "Chain expected to hook into exactly two devices"
|
|
+ exit 4
|
|
+}
|
|
+
|
|
+ip link del foo1
|
|
+$NFT list hooks netdev device foo1 | grep -q "$cspec" && {
|
|
+ echo "Chain still hooks into removed device foo1"
|
|
+ exit 5
|
|
+}
|
|
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
|
|
+ echo "Chain expected to hook into just lo"
|
|
+ exit 6
|
|
+}
|
|
+
|
|
+for ((i = 0; i < 100; i++)); do
|
|
+ ip link add foo$i type dummy
|
|
+done
|
|
+[[ $($NFT list hooks | grep -c "$cspec") -eq 101 ]] || {
|
|
+ echo "Chain did not hook into all 100 new devices"
|
|
+ exit 7
|
|
+}
|
|
diff --git a/tests/shell/testcases/flowtable/0016name_based_hook_0 b/tests/shell/testcases/flowtable/0016name_based_hook_0
|
|
new file mode 100755
|
|
index 0000000..9a55596
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/flowtable/0016name_based_hook_0
|
|
@@ -0,0 +1,45 @@
|
|
+#!/bin/bash
|
|
+
|
|
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
|
|
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_list_hooks_flowtable_info)
|
|
+
|
|
+ftspec=' flowtable ip t ft '
|
|
+$NFT add table t
|
|
+$NFT add $ftspec '{ hook ingress priority 0; devices = { lo, foo* }; }'
|
|
+$NFT list hooks netdev device lo | grep -q "$ftspec" || {
|
|
+ echo "Existing device lo not hooked into flowtable as expected"
|
|
+ exit 1
|
|
+}
|
|
+
|
|
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
|
|
+ echo "Flowtable hooks into more than just lo"
|
|
+ exit 2
|
|
+}
|
|
+
|
|
+ip link add foo1 type dummy
|
|
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" || {
|
|
+ echo "Flowtable did not hook into new device foo1"
|
|
+ exit 3
|
|
+}
|
|
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 2 ]] || {
|
|
+ echo "Flowtable expected to hook into exactly two devices"
|
|
+ exit 4
|
|
+}
|
|
+
|
|
+ip link del foo1
|
|
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" && {
|
|
+ echo "Flowtable still hooks into removed device foo1"
|
|
+ exit 5
|
|
+}
|
|
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
|
|
+ echo "Flowtable expected to hook into just lo"
|
|
+ exit 6
|
|
+}
|
|
+
|
|
+for ((i = 0; i < 100; i++)); do
|
|
+ ip link add foo$i type dummy
|
|
+done
|
|
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 101 ]] || {
|
|
+ echo "Flowtable did not hook into all 100 new devices"
|
|
+ exit 7
|
|
+}
|
|
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
|
|
new file mode 100644
|
|
index 0000000..93e2633
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
|
|
@@ -0,0 +1,32 @@
|
|
+{
|
|
+ "nftables": [
|
|
+ {
|
|
+ "metainfo": {
|
|
+ "version": "VERSION",
|
|
+ "release_name": "RELEASE_NAME",
|
|
+ "json_schema_version": 1
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "table": {
|
|
+ "family": "ip",
|
|
+ "name": "t",
|
|
+ "handle": 0
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "flowtable": {
|
|
+ "family": "ip",
|
|
+ "name": "ft",
|
|
+ "table": "t",
|
|
+ "handle": 0,
|
|
+ "hook": "ingress",
|
|
+ "prio": 0,
|
|
+ "dev": [
|
|
+ "foo*",
|
|
+ "lo"
|
|
+ ]
|
|
+ }
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
|
|
new file mode 100644
|
|
index 0000000..b481066
|
|
--- /dev/null
|
|
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
|
|
@@ -0,0 +1,6 @@
|
|
+table ip t {
|
|
+ flowtable ft {
|
|
+ hook ingress priority filter
|
|
+ devices = { "foo*", "lo" }
|
|
+ }
|
|
+}
|