* [PATCH nft] tests: shell: add packetpath test for nat on loopback
@ 2026-09-16 7:18 Florian Westphal
0 siblings, 0 replies; only message in thread
From: Florian Westphal @ 2026-09-16 7:18 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
Esoteric use case, but legal: NAT port rewrite over loopback.
Also add drop rule to ensure that the packet is still tracked
in input.
Assisted-by: LLM
Signed-off-by: Florian Westphal <fw@strlen.de>
---
.../packetpath/dumps/nat_lo.json-nft | 152 ++++++++++++++++++
.../testcases/packetpath/dumps/nat_lo.nft | 14 ++
tests/shell/testcases/packetpath/nat_lo | 42 +++++
3 files changed, 208 insertions(+)
create mode 100644 tests/shell/testcases/packetpath/dumps/nat_lo.json-nft
create mode 100644 tests/shell/testcases/packetpath/dumps/nat_lo.nft
create mode 100755 tests/shell/testcases/packetpath/nat_lo
diff --git a/tests/shell/testcases/packetpath/dumps/nat_lo.json-nft b/tests/shell/testcases/packetpath/dumps/nat_lo.json-nft
new file mode 100644
index 000000000000..1b8dca338ee0
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/nat_lo.json-nft
@@ -0,0 +1,152 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "inet",
+ "name": "nat",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "nat",
+ "name": "output",
+ "handle": 0,
+ "type": "nat",
+ "hook": "output",
+ "prio": -100,
+ "policy": "accept"
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "nat",
+ "chain": "output",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ "right": 1234
+ }
+ },
+ {
+ "redirect": {
+ "port": 12345
+ }
+ }
+ ]
+ }
+ },
+ {
+ "table": {
+ "family": "inet",
+ "name": "filter",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "filter",
+ "name": "input",
+ "handle": 0,
+ "type": "filter",
+ "hook": "input",
+ "prio": 0,
+ "policy": "drop"
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "in",
+ "left": {
+ "ct": {
+ "key": "state"
+ }
+ },
+ "right": [
+ "established",
+ "related",
+ "new"
+ ]
+ }
+ },
+ {
+ "accept": null
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "meta": {
+ "key": "l4proto"
+ }
+ },
+ "right": {
+ "set": [
+ 1,
+ 58
+ ]
+ }
+ }
+ },
+ {
+ "accept": null
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "counter": {
+ "packets": 0,
+ "bytes": 0
+ }
+ },
+ {
+ "drop": null
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/packetpath/dumps/nat_lo.nft b/tests/shell/testcases/packetpath/dumps/nat_lo.nft
new file mode 100644
index 000000000000..65259ec80242
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/nat_lo.nft
@@ -0,0 +1,14 @@
+table inet nat {
+ chain output {
+ type nat hook output priority dstnat; policy accept;
+ tcp dport 1234 redirect to :12345
+ }
+}
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ ct state established,related,new accept
+ meta l4proto { 1, 58 } accept
+ counter packets 0 bytes 0 drop
+ }
+}
diff --git a/tests/shell/testcases/packetpath/nat_lo b/tests/shell/testcases/packetpath/nat_lo
new file mode 100755
index 000000000000..862aadc82ef1
--- /dev/null
+++ b/tests/shell/testcases/packetpath/nat_lo
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -e
+
+$NFT -f - <<EOF
+table inet nat {
+ chain output {
+ type nat hook output priority dstnat; policy accept;
+ tcp dport 1234 redirect to :12345
+ }
+}
+
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ ct state new,established,related accept
+ meta l4proto { icmp, icmpv6 } accept
+ counter drop
+ }
+}
+EOF
+
+ip link set lo up
+
+# Start listener on the target port
+timeout 5 socat TCP6-LISTEN:12345,ipv6only=1,fork STDOUT &
+PID1=$!
+timeout 5 socat TCP4-LISTEN:12345,fork STDOUT &
+PID2=$!
+
+# Give socat a moment to bind
+sleep 1
+
+# Test IPv4 translation
+echo "Testing IPv4..."
+echo "hello ipv4" | socat -u STDIN TCP:127.0.0.1:1234
+
+# Test IPv6 translation
+echo "Testing IPv6..."
+echo "hello ipv6" | socat -u STDIN TCP:[::1]:1234
+
+kill $PID1 $PID2
--
2.55.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-16 7:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-16 7:18 [PATCH nft] tests: shell: add packetpath test for nat on loopback Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox