summaryrefslogtreecommitdiffstats
path: root/tests/shell/testcases/transactions
diff options
context:
space:
mode:
Diffstat (limited to 'tests/shell/testcases/transactions')
-rwxr-xr-xtests/shell/testcases/transactions/0001table_014
-rwxr-xr-xtests/shell/testcases/transactions/0002table_015
-rwxr-xr-xtests/shell/testcases/transactions/0003table_046
-rwxr-xr-xtests/shell/testcases/transactions/0010chain_015
-rwxr-xr-xtests/shell/testcases/transactions/0011chain_015
-rwxr-xr-xtests/shell/testcases/transactions/0012chain_019
-rwxr-xr-xtests/shell/testcases/transactions/0013chain_020
-rwxr-xr-xtests/shell/testcases/transactions/0014chain_110
-rwxr-xr-xtests/shell/testcases/transactions/0015chain_025
-rwxr-xr-xtests/shell/testcases/transactions/0020rule_014
-rwxr-xr-xtests/shell/testcases/transactions/0021rule_017
-rwxr-xr-xtests/shell/testcases/transactions/0022rule_111
-rwxr-xr-xtests/shell/testcases/transactions/0023rule_110
-rwxr-xr-xtests/shell/testcases/transactions/0024rule_017
-rwxr-xr-xtests/shell/testcases/transactions/0025rule_021
-rwxr-xr-xtests/shell/testcases/transactions/0030set_014
-rwxr-xr-xtests/shell/testcases/transactions/0031set_014
-rwxr-xr-xtests/shell/testcases/transactions/0032set_015
-rwxr-xr-xtests/shell/testcases/transactions/0033set_013
-rwxr-xr-xtests/shell/testcases/transactions/0034set_014
-rwxr-xr-xtests/shell/testcases/transactions/0035set_016
-rwxr-xr-xtests/shell/testcases/transactions/0036set_112
-rwxr-xr-xtests/shell/testcases/transactions/0037set_014
-rwxr-xr-xtests/shell/testcases/transactions/0038set_016
-rwxr-xr-xtests/shell/testcases/transactions/0039set_016
-rwxr-xr-xtests/shell/testcases/transactions/0040set_042
-rwxr-xr-xtests/shell/testcases/transactions/0041nat_restore_017
-rwxr-xr-xtests/shell/testcases/transactions/0042_stateful_expr_014
-rwxr-xr-xtests/shell/testcases/transactions/0043set_114
-rwxr-xr-xtests/shell/testcases/transactions/0044rule_022
-rwxr-xr-xtests/shell/testcases/transactions/0045anon-unbind_010
-rwxr-xr-xtests/shell/testcases/transactions/0046set_018
-rwxr-xr-xtests/shell/testcases/transactions/0047set_026
-rwxr-xr-xtests/shell/testcases/transactions/0048helpers_015
-rwxr-xr-xtests/shell/testcases/transactions/0049huge_067
-rwxr-xr-xtests/shell/testcases/transactions/0050rule_119
-rwxr-xr-xtests/shell/testcases/transactions/0051map_0122
-rwxr-xr-xtests/shell/testcases/transactions/30s-stress637
-rwxr-xr-xtests/shell/testcases/transactions/anon_chain_loop19
-rwxr-xr-xtests/shell/testcases/transactions/bad_expression38
-rw-r--r--tests/shell/testcases/transactions/dumps/0001table_0.nft4
-rw-r--r--tests/shell/testcases/transactions/dumps/0002table_0.nft7
-rw-r--r--tests/shell/testcases/transactions/dumps/0003table_0.nft4
-rw-r--r--tests/shell/testcases/transactions/dumps/0010chain_0.nft4
-rw-r--r--tests/shell/testcases/transactions/dumps/0011chain_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0012chain_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0013chain_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0014chain_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0015chain_0.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0020rule_0.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0021rule_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0022rule_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0023rule_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0024rule_0.nft8
-rw-r--r--tests/shell/testcases/transactions/dumps/0025rule_0.nft6
-rw-r--r--tests/shell/testcases/transactions/dumps/0030set_0.nft2
-rw-r--r--tests/shell/testcases/transactions/dumps/0031set_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0032set_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0033set_0.nft2
-rw-r--r--tests/shell/testcases/transactions/dumps/0034set_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0035set_0.nft6
-rw-r--r--tests/shell/testcases/transactions/dumps/0036set_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0037set_0.nft6
-rw-r--r--tests/shell/testcases/transactions/dumps/0038set_0.nft7
-rw-r--r--tests/shell/testcases/transactions/dumps/0039set_0.nft7
-rw-r--r--tests/shell/testcases/transactions/dumps/0040set_0.nft14
-rw-r--r--tests/shell/testcases/transactions/dumps/0041nat_restore_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0042_stateful_expr_0.nft5
-rw-r--r--tests/shell/testcases/transactions/dumps/0043set_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0044rule_0.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0045anon-unbind_0.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0046set_0.nft2
-rw-r--r--tests/shell/testcases/transactions/dumps/0047set_0.nft11
-rw-r--r--tests/shell/testcases/transactions/dumps/0048helpers_0.nft2
-rw-r--r--tests/shell/testcases/transactions/dumps/0049huge_0.nft749
-rw-r--r--tests/shell/testcases/transactions/dumps/0050rule_1.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/0051map_0.nodump0
-rw-r--r--tests/shell/testcases/transactions/dumps/30s-stress.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/anon_chain_loop.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/bad_expression.nft0
-rw-r--r--tests/shell/testcases/transactions/dumps/table_onoff.nft8
-rwxr-xr-xtests/shell/testcases/transactions/table_onoff44
82 files changed, 2431 insertions, 0 deletions
diff --git a/tests/shell/testcases/transactions/0001table_0 b/tests/shell/testcases/transactions/0001table_0
new file mode 100755
index 0000000..9929824
--- /dev/null
+++ b/tests/shell/testcases/transactions/0001table_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+delete table x
+add table x
+add table y"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0002table_0 b/tests/shell/testcases/transactions/0002table_0
new file mode 100755
index 0000000..c5f31a6
--- /dev/null
+++ b/tests/shell/testcases/transactions/0002table_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+delete table x
+add table x
+add chain x y { type nat hook prerouting priority 0; policy accept; }
+add table x { flags dormant; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0003table_0 b/tests/shell/testcases/transactions/0003table_0
new file mode 100755
index 0000000..91186de
--- /dev/null
+++ b/tests/shell/testcases/transactions/0003table_0
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add table y
+flush ruleset"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
+
+KERNEL_RULESET="$($NFT list ruleset)"
+if [ "" != "$KERNEL_RULESET" ] ; then
+ echo "Got a ruleset, but expected empty: "
+ echo "$KERNEL_RULESET"
+ exit 1
+fi
+
+RULESET="table ip x {
+}
+table ip y {
+}"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
+
+RULESETFAIL="flush ruleset
+create table ip nat
+create table inet filter
+create chain ip nat testchain
+delete table ip testtable"
+
+# testtable doesn't exist, batch expected to fail
+$NFT -f - <<< "$RULESETFAIL" && exit 2
+
+KERNEL_RULESET="$($NFT list ruleset)"
+if [ "$RULESET" != "$KERNEL_RULESET" ] ; then
+ $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET")
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0010chain_0 b/tests/shell/testcases/transactions/0010chain_0
new file mode 100755
index 0000000..ce66bd6
--- /dev/null
+++ b/tests/shell/testcases/transactions/0010chain_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+flush ruleset
+add table w
+add chain w y"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0011chain_0 b/tests/shell/testcases/transactions/0011chain_0
new file mode 100755
index 0000000..3bed16d
--- /dev/null
+++ b/tests/shell/testcases/transactions/0011chain_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+delete chain x y
+add chain x y { type filter hook input priority 0; }
+add chain x y { policy drop; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0012chain_0 b/tests/shell/testcases/transactions/0012chain_0
new file mode 100755
index 0000000..0d80ef4
--- /dev/null
+++ b/tests/shell/testcases/transactions/0012chain_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+flush ruleset
+add table x
+add chain x y { type filter hook input priority 0; }
+add chain x y { policy drop; }
+flush ruleset
+add table w
+add chain w y { type filter hook output priority 0; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0013chain_0 b/tests/shell/testcases/transactions/0013chain_0
new file mode 100755
index 0000000..2756dd6
--- /dev/null
+++ b/tests/shell/testcases/transactions/0013chain_0
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+delete chain x y
+delete table x
+add table x
+add chain x y { type filter hook input priority 0; }
+add chain x y { policy drop; }
+flush ruleset
+add table w
+add chain w y { type filter hook output priority 0; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0014chain_1 b/tests/shell/testcases/transactions/0014chain_1
new file mode 100755
index 0000000..cddc8a2
--- /dev/null
+++ b/tests/shell/testcases/transactions/0014chain_1
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+RULESET="add table x
+add chain x y
+delete chain x y
+delete chain x y"
+
+$NFT -f - <<< "$RULESET" 2>/dev/null || exit 0
+echo "E: allowing double-removal of chain" >&2
+exit 1
diff --git a/tests/shell/testcases/transactions/0015chain_0 b/tests/shell/testcases/transactions/0015chain_0
new file mode 100755
index 0000000..42950b3
--- /dev/null
+++ b/tests/shell/testcases/transactions/0015chain_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+add chain x z
+add rule x z jump y"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
+
+RULESET="delete rule x z handle 3
+delete chain x z
+delete chain x y
+delete table x"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0020rule_0 b/tests/shell/testcases/transactions/0020rule_0
new file mode 100755
index 0000000..f8d2d37
--- /dev/null
+++ b/tests/shell/testcases/transactions/0020rule_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+add rule x y ip saddr 1.1.1.1 counter
+flush ruleset"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0021rule_0 b/tests/shell/testcases/transactions/0021rule_0
new file mode 100755
index 0000000..ee265ab
--- /dev/null
+++ b/tests/shell/testcases/transactions/0021rule_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add chain x y
+add rule x y ip saddr 1.1.1.1 counter
+flush ruleset
+add table x
+add chain x y
+add rule x y ip saddr 2.2.2.2 counter"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0022rule_1 b/tests/shell/testcases/transactions/0022rule_1
new file mode 100755
index 0000000..07be53f
--- /dev/null
+++ b/tests/shell/testcases/transactions/0022rule_1
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+RULESET="add table x
+add chain x y
+delete chain x y
+add rule x y jump y"
+
+# kernel must return ENOENT
+$NFT -f - <<< "$RULESET" 2>/dev/null || exit 0
+echo "E: allowing jump loop to unexisting chain"
+exit 1
diff --git a/tests/shell/testcases/transactions/0023rule_1 b/tests/shell/testcases/transactions/0023rule_1
new file mode 100755
index 0000000..e58c088
--- /dev/null
+++ b/tests/shell/testcases/transactions/0023rule_1
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+RULESET="add table x
+add chain x y
+add rule x y jump y"
+
+# kernel must return ELOOP
+$NFT -f - <<< "$RULESET" 2>/dev/null || exit 0
+echo "E: allowing jump to chain loop"
+exit 1
diff --git a/tests/shell/testcases/transactions/0024rule_0 b/tests/shell/testcases/transactions/0024rule_0
new file mode 100755
index 0000000..4c1ac41
--- /dev/null
+++ b/tests/shell/testcases/transactions/0024rule_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+RULESET="flush ruleset
+add table x
+add chain x y
+add rule x y accept comment rule1
+add rule x y accept comment rule4
+add rule x y index 0 accept comment rule2
+insert rule x y index 2 accept comment rule3"
+
+$NFT -f - <<< "$RULESET" && \
+ $NFT -f - <<< "$RULESET" && \
+ echo "$RULESET" | tr '\n' ';' | $NFT -i >/dev/null && \
+ exit 0
+echo "E: intra-transaction rule reference failed"
+exit 1
+
diff --git a/tests/shell/testcases/transactions/0025rule_0 b/tests/shell/testcases/transactions/0025rule_0
new file mode 100755
index 0000000..d72d5cf
--- /dev/null
+++ b/tests/shell/testcases/transactions/0025rule_0
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# make sure stored delete/replace rule commands are correctly applied
+
+set -e
+
+$NFT -f - <<EOF
+flush ruleset
+table x {
+ chain y {
+ accept
+ log
+ }
+}
+EOF
+
+$NFT -f - <<EOF
+replace rule x y handle 2 log
+delete rule x y handle 3
+add rule x y index 0 drop
+EOF
diff --git a/tests/shell/testcases/transactions/0030set_0 b/tests/shell/testcases/transactions/0030set_0
new file mode 100755
index 0000000..e17b42f
--- /dev/null
+++ b/tests/shell/testcases/transactions/0030set_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+flush ruleset
+add table x"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0031set_0 b/tests/shell/testcases/transactions/0031set_0
new file mode 100755
index 0000000..b2133cf
--- /dev/null
+++ b/tests/shell/testcases/transactions/0031set_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+delete set x y
+add set x y { type ipv4_addr; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0032set_0 b/tests/shell/testcases/transactions/0032set_0
new file mode 100755
index 0000000..5882518
--- /dev/null
+++ b/tests/shell/testcases/transactions/0032set_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+flush ruleset
+add table w
+add set w y { type ipv4_addr; }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0033set_0 b/tests/shell/testcases/transactions/0033set_0
new file mode 100755
index 0000000..6bd5893
--- /dev/null
+++ b/tests/shell/testcases/transactions/0033set_0
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+delete set x y"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0034set_0 b/tests/shell/testcases/transactions/0034set_0
new file mode 100755
index 0000000..1580c32
--- /dev/null
+++ b/tests/shell/testcases/transactions/0034set_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+add element x y { 1.1.1.1 }
+delete element x y { 1.1.1.1 }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0035set_0 b/tests/shell/testcases/transactions/0035set_0
new file mode 100755
index 0000000..0967fd4
--- /dev/null
+++ b/tests/shell/testcases/transactions/0035set_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+add element x y { 1.1.1.1, 2.2.2.2 }
+delete element x y { 1.1.1.1 }
+delete element x y { 2.2.2.2 }
+add element x y { 3.3.3.3 }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0036set_1 b/tests/shell/testcases/transactions/0036set_1
new file mode 100755
index 0000000..45d922e
--- /dev/null
+++ b/tests/shell/testcases/transactions/0036set_1
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+RULESET="add table x
+add set x y { type ipv4_addr; }
+add element x y { 1.1.1.1, 2.2.2.2 }
+delete element x y { 1.1.1.1 }
+delete element x y { 1.1.1.1 }"
+
+$NFT -f - <<< "$RULESET" 2> /dev/null || exit 0
+# Kernel must return ENOENT
+echo "E: allowing double-removal of element"
+exit 1
diff --git a/tests/shell/testcases/transactions/0037set_0 b/tests/shell/testcases/transactions/0037set_0
new file mode 100755
index 0000000..2882863
--- /dev/null
+++ b/tests/shell/testcases/transactions/0037set_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; flags interval;}
+add element x y { 1.1.1.0/24 }
+delete element x y { 1.1.1.0/24 }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0038set_0 b/tests/shell/testcases/transactions/0038set_0
new file mode 100755
index 0000000..d7c2ba3
--- /dev/null
+++ b/tests/shell/testcases/transactions/0038set_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; flags interval;}
+add element x y { 192.168.0.0/24, 192.168.2.0/24 }
+delete element x y { 192.168.0.0/24 }
+delete element x y { 192.168.2.0/24 }
+add element x y { 192.168.4.0/24 }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0039set_0 b/tests/shell/testcases/transactions/0039set_0
new file mode 100755
index 0000000..d7c2ba3
--- /dev/null
+++ b/tests/shell/testcases/transactions/0039set_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table x
+add set x y { type ipv4_addr; flags interval;}
+add element x y { 192.168.0.0/24, 192.168.2.0/24 }
+delete element x y { 192.168.0.0/24 }
+delete element x y { 192.168.2.0/24 }
+add element x y { 192.168.4.0/24 }"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0040set_0 b/tests/shell/testcases/transactions/0040set_0
new file mode 100755
index 0000000..468816b
--- /dev/null
+++ b/tests/shell/testcases/transactions/0040set_0
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip filter {
+ map client_to_any {
+ type ipv4_addr : verdict
+ elements = { 1.2.3.4 : goto CIn_1 }
+ }
+
+ chain FORWARD {
+ type filter hook forward priority filter; policy accept;
+ goto client_to_any
+ }
+
+ chain client_to_any {
+ ip saddr vmap @client_to_any
+ }
+
+ chain CIn_1 {
+ }
+}"
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
+
+GET="$($NFT list ruleset)"
+
+if [ "$RULESET" != "$GET" ] ; then
+ $DIFF -u <(echo "$RULESET") <(echo "$GET")
+ exit 1
+fi
+
+RULESET="delete element ip filter client_to_any { 1.2.3.4 : goto CIn_1 }
+delete chain ip filter CIn_1"
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0041nat_restore_0 b/tests/shell/testcases/transactions/0041nat_restore_0
new file mode 100755
index 0000000..9e1d6c9
--- /dev/null
+++ b/tests/shell/testcases/transactions/0041nat_restore_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+add table ip t
+add chain ip t c { type nat hook postrouting priority 0; }
+"
+
+$NFT -f - <<< "$RULESET"
+
+RULESET="
+flush ruleset
+$RULESET
+"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0042_stateful_expr_0 b/tests/shell/testcases/transactions/0042_stateful_expr_0
new file mode 100755
index 0000000..918e721
--- /dev/null
+++ b/tests/shell/testcases/transactions/0042_stateful_expr_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+add table ip filter
+add counter ip filter c1
+add map ip filter m1 { type ipv4_addr : counter ;}
+add element ip filter m1 { 1 : c1 }
+add element ip filter m1 { 1 : c1 }
+delete element ip filter m1 { 1 }
+delete counter ip filter c1"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0043set_1 b/tests/shell/testcases/transactions/0043set_1
new file mode 100755
index 0000000..a9135c1
--- /dev/null
+++ b/tests/shell/testcases/transactions/0043set_1
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+RULESET="add table ip test
+add set ip test foo { type ipv4_addr; }
+add chain ip test tc
+add element ip test foo { 1.2.3.4 }
+add rule ip test tc ip saddr { 1.2.3.4, 5.6.7.8 } accept
+delete table ip test
+add element ip test foo { 1.2.3.6 }"
+
+# kernel must return ENOENT
+$NFT -f - <<< "$RULESET" 2>/dev/null || exit 0
+echo "E: allowing element insertion on unexisting set"
+exit 1
diff --git a/tests/shell/testcases/transactions/0044rule_0 b/tests/shell/testcases/transactions/0044rule_0
new file mode 100755
index 0000000..a4da480
--- /dev/null
+++ b/tests/shell/testcases/transactions/0044rule_0
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+RULESET="add table ip test
+add chain ip test tc
+add rule ip test tc counter"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
+
+RULESET="delete rule ip test tc handle 2
+flush ruleset"
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load good ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/transactions/0045anon-unbind_0 b/tests/shell/testcases/transactions/0045anon-unbind_0
new file mode 100755
index 0000000..1e16af1
--- /dev/null
+++ b/tests/shell/testcases/transactions/0045anon-unbind_0
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+RULESET='table inet filter {
+ chain antileak {
+ udp dport { 137, 138 } drop comment "NetBT"
+ }
+}'
+
+set -e
+$NFT -c -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0046set_0 b/tests/shell/testcases/transactions/0046set_0
new file mode 100755
index 0000000..172e24d
--- /dev/null
+++ b/tests/shell/testcases/transactions/0046set_0
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+RULESET='add table ip filter
+add chain ip filter group_7933
+add map ip filter group_7933 { type ipv4_addr : classid; flags interval; }
+add rule ip filter group_7933 meta priority 0 meta priority set ip saddr map @group_7933 counter
+add element ip filter group_7933 { 10.4.22.0/24 : "1:0xc7cb" }
+'
+
+set -e
+$NFT -f - <<< "$RULESET"
+
+RULESET='delete element ip filter group_7933 { 10.4.22.0/24 }
+flush chain ip filter group_7933
+delete chain ip filter group_7933
+delete map ip filter group_7933'
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0047set_0 b/tests/shell/testcases/transactions/0047set_0
new file mode 100755
index 0000000..0a27231
--- /dev/null
+++ b/tests/shell/testcases/transactions/0047set_0
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+RULESET='add table ip filter
+add map ip filter group_10060 { type ipv4_addr : classid; flags interval; }
+add element ip filter group_10060 { 10.1.26.2/32 : "1:0xbbf8" }
+add element ip filter group_10060 { 10.1.26.3/32 : "1:0xc1ad" }
+add element ip filter group_10060 { 10.1.26.4/32 : "1:0xb2d7" }
+add element ip filter group_10060 { 10.1.26.5/32 : "1:0xf705" }
+add element ip filter group_10060 { 10.1.26.6/32 : "1:0xb895" }
+add element ip filter group_10060 { 10.1.26.7/32 : "1:0xec4c" }
+add element ip filter group_10060 { 10.1.26.8/32 : "1:0xde78" }
+add element ip filter group_10060 { 10.1.26.9/32 : "1:0xb4f3" }
+add element ip filter group_10060 { 10.1.26.10/32 : "1:0xdec6" }
+add element ip filter group_10060 { 10.1.26.11/32 : "1:0xb4c0" }
+add element ip filter group_10060 { 10.1.26.12/32 : "1:0xb4a2" }
+add element ip filter group_10060 { 10.1.26.13/32 : "1:0xa8ab" }
+add element ip filter group_10060 { 10.1.26.14/32 : "1:0xb3c1" }'
+
+set -e
+$NFT -f - <<< "$RULESET"
+
+RULESET='delete element ip filter group_10060 { 10.1.26.13/32 }
+delete element ip filter group_10060 { 10.1.26.14/32 }
+delete element ip filter group_10060 { 10.1.26.12/32 }'
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0048helpers_0 b/tests/shell/testcases/transactions/0048helpers_0
new file mode 100755
index 0000000..675a977
--- /dev/null
+++ b/tests/shell/testcases/transactions/0048helpers_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+RULESET='add table ip filter
+add chain ip filter filter { type filter hook prerouting priority mangle; policy accept; }
+add ct helper ip filter ftp { type "ftp" protocol tcp; };
+add rule ip filter filter tcp dport 33 ct helper set "ftp"'
+
+set -e
+$NFT -f - <<< "$RULESET"
+
+RULESET='flush chain ip filter filter
+delete chain filter filter
+delete ct helper ip filter ftp'
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/transactions/0049huge_0 b/tests/shell/testcases/transactions/0049huge_0
new file mode 100755
index 0000000..f66953c
--- /dev/null
+++ b/tests/shell/testcases/transactions/0049huge_0
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+# let's try to exceed transaction buffer space
+
+$NFT flush ruleset
+$NFT add table inet test
+$NFT add chain inet test c
+
+RULE_COUNT=3000
+
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/rmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ RULE_COUNT=500
+fi
+
+RULESET=$(
+for ((i = 0; i < ${RULE_COUNT}; i++)); do
+ echo "add rule inet test c accept comment rule$i"
+done
+)
+test $($NFT -e -a -f - <<< "$RULESET" |grep "#[ ]\+handle[ ]\+[0-9]\+" |wc -l) -eq ${RULE_COUNT} || exit 1
+
+# same thing, but with JSON rules
+#
+$NFT flush ruleset
+$NFT add table inet test
+$NFT add chain inet test c
+
+RULESET=$(
+echo '{"nftables": ['
+for ((i = 0; i < $((${RULE_COUNT} - 1)); i++)); do
+ echo '{"add": {"rule": {"family": "inet", "table": "test", "chain": "c", "expr": [{"accept": null}], "comment": "rule'$i'"}}},'
+done
+ echo '{"add": {"rule": {"family": "inet", "table": "test", "chain": "c", "expr": [{"accept": null}], "comment": "rule'$((${RULE_COUNT} - 1))'"}}}'
+echo ']}'
+)
+
+if [ "$NFT_TEST_HAVE_json" != n ]; then
+ test $($NFT -j -e -a -f - <<< "$RULESET" |sed 's/\({"add":\)/\n\1/g' |grep '"handle"' |wc -l) -eq ${RULE_COUNT} || exit 1
+fi
+
+# Now an example from firewalld's testsuite
+#
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"json_schema_version": 1}}, {"add": {"table": {"family": "inet", "name": "firewalld"}}}, {"add": {"table": {"family": "ip", "name": "firewalld"}}}, {"add": {"table": {"family": "ip6", "name": "firewalld"}}},
+{"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PREROUTING", "type": "filter", "hook": "prerouting", "prio": -290}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PREROUTING_ZONES"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING", "expr": [{"jump": {"target": "raw_PREROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PREROUTING", "type": "filter", "hook": "prerouting", "prio": -140}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PREROUTING_ZONES"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PREROUTING", "expr": [{"jump": {"target": "mangle_PREROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PREROUTING", "type": "nat", "hook": "prerouting", "prio": -90}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PREROUTING_ZONES"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PREROUTING", "expr": [{"jump": {"target": "nat_PREROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POSTROUTING", "type": "nat", "hook": "postrouting", "prio": 110}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POSTROUTING_ZONES"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POSTROUTING", "expr": [{"jump": {"target": "nat_POSTROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PREROUTING", "type": "nat", "hook": "prerouting", "prio": -90}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PREROUTING_ZONES"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PREROUTING", "expr": [{"jump": {"target": "nat_PREROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POSTROUTING", "type": "nat", "hook": "postrouting", "prio": 110}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POSTROUTING_ZONES"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POSTROUTING", "expr": [{"jump": {"target": "nat_POSTROUTING_ZONES"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_INPUT", "type": "filter", "hook": "input", "prio": 10}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FORWARD", "type": "filter", "hook": "forward", "prio": 10}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_OUTPUT", "type": "filter", "hook": "output", "prio": 10}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_INPUT_ZONES"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["established", "related"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"match": {"left": {"ct": {"key": "status"}}, "op": "in", "right": "dnat"}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "lo"}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"jump": {"target": "filter_INPUT_ZONES"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["invalid"]}}}, {"drop": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT", "expr": [{"reject": {"type": "icmpx", "expr": "admin-prohibited"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FORWARD_IN_ZONES"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FORWARD_OUT_ZONES"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["established", "related"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"match": {"left": {"ct": {"key": "status"}}, "op": "in", "right": "dnat"}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "lo"}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"jump": {"target": "filter_FORWARD_IN_ZONES"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"jump": {"target": "filter_FORWARD_OUT_ZONES"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["invalid"]}}}, {"drop": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "expr": [{"reject": {"type": "icmpx", "expr": "admin-prohibited"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_OUTPUT", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "lo"}}, {"accept": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING", "expr": [{"match": {"left": {"meta": {"key": "nfproto"}}, "op": "==", "right": "ipv6"}}, {"match": {"left": {"fib": {"flags": ["saddr", "iif"], "result": "oif"}}, "op": "==", "right": false}}, {"drop": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING", "expr": [{"match": {"left": {"payload": {"protocol": "icmpv6", "field": "type"}}, "op": "==", "right": {"set": ["nd-router-advert", "nd-neighbor-solicit"]}}}, {"accept": null}]}}},
+{"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_OUTPUT", "index": 0, "expr": [{"match": {"left": {"payload": {"protocol": "ip6", "field": "daddr"}}, "op": "==", "right": {"set": [{"prefix": {"addr": "::0.0.0.0", "len": 96}}, {"prefix": {"addr": "::ffff:0.0.0.0", "len": 96}}, {"prefix": {"addr": "2002:0000::", "len": 24}}, {"prefix": {"addr": "2002:0a00::", "len": 24}}, {"prefix": {"addr": "2002:7f00::", "len": 24}}, {"prefix": {"addr": "2002:ac10::", "len": 28}}, {"prefix": {"addr": "2002:c0a8::", "len": 32}}, {"prefix": {"addr": "2002:a9fe::", "len": 32}}, {"prefix": {"addr": "2002:e000::", "len": 19}}]}}}, {"reject": {"type": "icmpv6", "expr": "addr-unreachable"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD", "index": 2, "expr": [{"match": {"left": {"payload": {"protocol": "ip6", "field": "daddr"}}, "op": "==", "right": {"set": [{"prefix": {"addr": "::0.0.0.0", "len": 96}}, {"prefix": {"addr": "::ffff:0.0.0.0", "len": 96}}, {"prefix": {"addr": "2002:0000::", "len": 24}}, {"prefix": {"addr": "2002:0a00::", "len": 24}}, {"prefix": {"addr": "2002:7f00::", "len": 24}}, {"prefix": {"addr": "2002:ac10::", "len": 28}}, {"prefix": {"addr": "2002:c0a8::", "len": 32}}, {"prefix": {"addr": "2002:a9fe::", "len": 32}}, {"prefix": {"addr": "2002:e000::", "len": 19}}]}}}, {"reject": {"type": "icmpv6", "expr": "addr-unreachable"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_public_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_public", "expr": [{"jump": {"target": "raw_PRE_public_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_public", "expr": [{"jump": {"target": "raw_PRE_public_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_public", "expr": [{"jump": {"target": "raw_PRE_public_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_public", "expr": [{"jump": {"target": "raw_PRE_public_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_public", "expr": [{"jump": {"target": "raw_PRE_public_post"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_public_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "expr": [{"jump": {"target": "filter_IN_public_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "expr": [{"jump": {"target": "filter_IN_public_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "expr": [{"jump": {"target": "filter_IN_public_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "expr": [{"jump": {"target": "filter_IN_public_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "expr": [{"jump": {"target": "filter_IN_public_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public_allow", "expr": [{"match": {"left": {"payload": {"protocol": "tcp", "field": "dport"}}, "op": "==", "right": 22}}, {"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["new", "untracked"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public_allow", "expr": [{"match": {"left": {"payload": {"protocol": "ip6", "field": "daddr"}}, "op": "==", "right": {"prefix": {"addr": "fe80::", "len": 64}}}}, {"match": {"left": {"payload": {"protocol": "udp", "field": "dport"}}, "op": "==", "right": 546}}, {"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["new", "untracked"]}}}, {"accept": null}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_public_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "expr": [{"jump": {"target": "filter_FWDI_public_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "expr": [{"jump": {"target": "filter_FWDI_public_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "expr": [{"jump": {"target": "filter_FWDI_public_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "expr": [{"jump": {"target": "filter_FWDI_public_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "expr": [{"jump": {"target": "filter_FWDI_public_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_public", "index": 4, "expr": [{"match": {"left": {"meta": {"key": "l4proto"}}, "op": "==", "right": {"set": ["icmp", "icmpv6"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_public", "index": 4, "expr": [{"match": {"left": {"meta": {"key": "l4proto"}}, "op": "==", "right": {"set": ["icmp", "icmpv6"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING_ZONES", "expr": [{"goto": {"target": "raw_PRE_public"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_public_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_public", "expr": [{"jump": {"target": "mangle_PRE_public_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_public", "expr": [{"jump": {"target": "mangle_PRE_public_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_public", "expr": [{"jump": {"target": "mangle_PRE_public_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_public", "expr": [{"jump": {"target": "mangle_PRE_public_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_public", "expr": [{"jump": {"target": "mangle_PRE_public_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PREROUTING_ZONES", "expr": [{"goto": {"target": "mangle_PRE_public"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_public_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_public_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_public", "expr": [{"jump": {"target": "nat_PRE_public_post"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"goto": {"target": "nat_PRE_public"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"goto": {"target": "nat_PRE_public"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_public_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_public_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_public", "expr": [{"jump": {"target": "nat_POST_public_post"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"goto": {"target": "nat_POST_public"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"goto": {"target": "nat_POST_public"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT_ZONES", "expr": [{"goto": {"target": "filter_IN_public"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_IN_ZONES", "expr": [{"goto": {"target": "filter_FWDI_public"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_public_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_public", "expr": [{"jump": {"target": "filter_FWDO_public_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_public", "expr": [{"jump": {"target": "filter_FWDO_public_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_public", "expr": [{"jump": {"target": "filter_FWDO_public_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_public", "expr": [{"jump": {"target": "filter_FWDO_public_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_public", "expr": [{"jump": {"target": "filter_FWDO_public_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_OUT_ZONES", "expr": [{"goto": {"target": "filter_FWDO_public"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_trusted_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_trusted", "expr": [{"jump": {"target": "raw_PRE_trusted_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_trusted", "expr": [{"jump": {"target": "raw_PRE_trusted_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_trusted", "expr": [{"jump": {"target": "raw_PRE_trusted_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_trusted", "expr": [{"jump": {"target": "raw_PRE_trusted_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_trusted", "expr": [{"jump": {"target": "raw_PRE_trusted_post"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "raw_PRE_trusted"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_trusted_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_trusted", "expr": [{"jump": {"target": "mangle_PRE_trusted_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_trusted", "expr": [{"jump": {"target": "mangle_PRE_trusted_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_trusted", "expr": [{"jump": {"target": "mangle_PRE_trusted_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_trusted", "expr": [{"jump": {"target": "mangle_PRE_trusted_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_trusted", "expr": [{"jump": {"target": "mangle_PRE_trusted_post"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "mangle_PRE_trusted"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_trusted_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_trusted_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_trusted", "expr": [{"jump": {"target": "nat_PRE_trusted_post"}}]}}}, {"insert": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "nat_PRE_trusted"}}]}}}, {"insert": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "nat_PRE_trusted"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_trusted_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_trusted_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_trusted", "expr": [{"jump": {"target": "nat_POST_trusted_post"}}]}}}, {"insert": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "nat_POST_trusted"}}]}}}, {"insert": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "nat_POST_trusted"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_trusted_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"jump": {"target": "filter_IN_trusted_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"jump": {"target": "filter_IN_trusted_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"jump": {"target": "filter_IN_trusted_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"jump": {"target": "filter_IN_trusted_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"jump": {"target": "filter_IN_trusted_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_trusted", "expr": [{"accept": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "filter_IN_trusted"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_trusted_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"jump": {"target": "filter_FWDI_trusted_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"jump": {"target": "filter_FWDI_trusted_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"jump": {"target": "filter_FWDI_trusted_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"jump": {"target": "filter_FWDI_trusted_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"jump": {"target": "filter_FWDI_trusted_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_trusted", "expr": [{"accept": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_IN_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "filter_FWDI_trusted"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_trusted_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"jump": {"target": "filter_FWDO_trusted_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"jump": {"target": "filter_FWDO_trusted_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"jump": {"target": "filter_FWDO_trusted_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"jump": {"target": "filter_FWDO_trusted_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"jump": {"target": "filter_FWDO_trusted_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_trusted", "expr": [{"accept": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_OUT_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy2"}}, {"goto": {"target": "filter_FWDO_trusted"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "raw_PRE_work_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_work", "expr": [{"jump": {"target": "raw_PRE_work_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_work", "expr": [{"jump": {"target": "raw_PRE_work_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_work", "expr": [{"jump": {"target": "raw_PRE_work_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_work", "expr": [{"jump": {"target": "raw_PRE_work_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PRE_work", "expr": [{"jump": {"target": "raw_PRE_work_post"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_IN_work_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "expr": [{"jump": {"target": "filter_IN_work_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "expr": [{"jump": {"target": "filter_IN_work_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "expr": [{"jump": {"target": "filter_IN_work_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "expr": [{"jump": {"target": "filter_IN_work_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "expr": [{"jump": {"target": "filter_IN_work_post"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work_allow", "expr": [{"match": {"left": {"payload": {"protocol": "tcp", "field": "dport"}}, "op": "==", "right": 22}}, {"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["new", "untracked"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work_allow", "expr": [{"match": {"left": {"payload": {"protocol": "ip6", "field": "daddr"}}, "op": "==", "right": {"prefix": {"addr": "fe80::", "len": 64}}}}, {"match": {"left": {"payload": {"protocol": "udp", "field": "dport"}}, "op": "==", "right": 546}}, {"match": {"left": {"ct": {"key": "state"}}, "op": "in", "right": {"set": ["new", "untracked"]}}}, {"accept": null}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "raw_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "raw_PRE_work"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "mangle_PRE_work_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_work", "expr": [{"jump": {"target": "mangle_PRE_work_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_work", "expr": [{"jump": {"target": "mangle_PRE_work_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_work", "expr": [{"jump": {"target": "mangle_PRE_work_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_work", "expr": [{"jump": {"target": "mangle_PRE_work_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PRE_work", "expr": [{"jump": {"target": "mangle_PRE_work_post"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "mangle_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "mangle_PRE_work"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_PRE_work_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_PRE_work_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PRE_work", "expr": [{"jump": {"target": "nat_PRE_work_post"}}]}}}, {"insert": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "nat_PRE_work"}}]}}}, {"insert": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_PREROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "nat_PRE_work"}}]}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work_pre"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work_log"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work_deny"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work_allow"}}}, {"add": {"chain": {"family": "ip", "table": "firewalld", "name": "nat_POST_work_post"}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_pre"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_log"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_deny"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_allow"}}]}}}, {"add": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_post"}}]}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work_pre"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work_log"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work_deny"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work_allow"}}}, {"add": {"chain": {"family": "ip6", "table": "firewalld", "name": "nat_POST_work_post"}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_pre"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_log"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_deny"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_allow"}}]}}}, {"add": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POST_work", "expr": [{"jump": {"target": "nat_POST_work_post"}}]}}}, {"insert": {"rule": {"family": "ip", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "nat_POST_work"}}]}}}, {"insert": {"rule": {"family": "ip6", "table": "firewalld", "chain": "nat_POSTROUTING_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "nat_POST_work"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_INPUT_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "filter_IN_work"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDI_work_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "expr": [{"jump": {"target": "filter_FWDI_work_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "expr": [{"jump": {"target": "filter_FWDI_work_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "expr": [{"jump": {"target": "filter_FWDI_work_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "expr": [{"jump": {"target": "filter_FWDI_work_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "expr": [{"jump": {"target": "filter_FWDI_work_post"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_IN_ZONES", "expr": [{"match": {"left": {"meta": {"key": "iifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "filter_FWDI_work"}}]}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work_pre"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work_log"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work_deny"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work_allow"}}}, {"add": {"chain": {"family": "inet", "table": "firewalld", "name": "filter_FWDO_work_post"}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_work", "expr": [{"jump": {"target": "filter_FWDO_work_pre"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_work", "expr": [{"jump": {"target": "filter_FWDO_work_log"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_work", "expr": [{"jump": {"target": "filter_FWDO_work_deny"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_work", "expr": [{"jump": {"target": "filter_FWDO_work_allow"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDO_work", "expr": [{"jump": {"target": "filter_FWDO_work_post"}}]}}}, {"insert": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FORWARD_OUT_ZONES", "expr": [{"match": {"left": {"meta": {"key": "oifname"}}, "op": "==", "right": "perm_dummy"}}, {"goto": {"target": "filter_FWDO_work"}}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_IN_work", "index": 4, "expr": [{"match": {"left": {"meta": {"key": "l4proto"}}, "op": "==", "right": {"set": ["icmp", "icmpv6"]}}}, {"accept": null}]}}}, {"add": {"rule": {"family": "inet", "table": "firewalld", "chain": "filter_FWDI_work", "index": 4, "expr": [{"match": {"left": {"meta": {"key": "l4proto"}}, "op": "==", "right": {"set": ["icmp", "icmpv6"]}}}, {"accept": null}]}}}]}'
+
+if [ "$NFT_TEST_HAVE_json" != n ]; then
+ test -z "$($NFT -j -e -a -f - <<< "$RULESET" |sed 's/\({"add":\|{"insert":\)/\n\1/g' |grep '\({"add":\|{"insert":\)' | grep -v '"handle"')"
+fi
+
+if [ "$NFT_TEST_HAVE_json" = n ]; then
+ echo "Test partially skipped due to missing JSON support."
+ exit 77
+fi
+
+if [ "$RULE_COUNT" != 3000 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/rmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/transactions/0050rule_1 b/tests/shell/testcases/transactions/0050rule_1
new file mode 100755
index 0000000..89e5f42
--- /dev/null
+++ b/tests/shell/testcases/transactions/0050rule_1
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet filter {
+ flowtable ftable {
+ hook ingress priority 0; devices = { eno1, eno0, x };
+ }
+
+chain forward {
+ type filter hook forward priority 0; policy drop;
+
+ ip protocol { tcp, udp } ct mark and 1 == 1 counter flow add @ftable
+ ip6 nexthdr { tcp, udp } ct mark and 2 == 2 counter flow add @ftable
+ ct mark and 30 == 30 ct state established,related log prefix \"nftables accept: \" level info accept
+ }
+}"
+
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
diff --git a/tests/shell/testcases/transactions/0051map_0 b/tests/shell/testcases/transactions/0051map_0
new file mode 100755
index 0000000..9ea5cd4
--- /dev/null
+++ b/tests/shell/testcases/transactions/0051map_0
@@ -0,0 +1,122 @@
+#!/bin/bash
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1trans-$rnd"
+
+#
+# dependency tracking for implicit set
+#
+RULESET="table ip x {
+ chain w {}
+ chain m {}
+
+ chain y {
+ ip saddr vmap { 1.1.1.1 : jump w, 2.2.2.2 : accept, 3.3.3.3 : goto m }
+ }
+}"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns add $ns1
+ip netns exec $ns1 $NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns del $ns1
+
+RULESET="flush chain ip x y
+delete chain ip x w"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+
+#
+# dependency tracking for map in implicit chain
+#
+RULESET="table ip x {
+ chain w {}
+ chain m {}
+
+ chain y {
+ meta iifname \"eno1\" jump {
+ ip saddr vmap { 1.1.1.1 : jump w, 3.3.3.3 : goto m }
+ }
+ }
+}"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns add $ns1
+ip netns exec $ns1 $NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns del $ns1
+
+RULESET="flush chain ip x y
+delete chain ip x w"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+
+#
+# dependency tracking for explicit map
+#
+RULESET="table ip x {
+ chain w {}
+ chain m {}
+
+ map y {
+ type ipv4_addr : verdict
+ elements = { 1.1.1.1 : jump w, 2.2.2.2 : accept, 3.3.3.3 : goto m }
+ }
+}"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns add $ns1
+ip netns exec $ns1 $NFT -f - <<< "$RULESET" >/dev/null || exit 0
+ip netns del $ns1
+
+RULESET="delete set ip x y
+delete chain ip x w"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+
+#
+# error path for implicit set
+#
+RULESET="table inet filter {
+ chain w {
+ jump z
+ }
+ chain z {
+ jump w
+ }
+
+ chain test {
+ ip protocol { tcp, udp } ip saddr vmap { 1.1.1.1 : jump z } counter flow add @nonexisting
+ ip6 nexthdr { tcp, udp } ct mark and 2 == 2 counter
+ }
+}"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+
+#
+# error path for implicit set
+#
+RULESET="table inet filter {
+ chain w {
+ jump z
+ }
+ chain z {
+ jump w
+ }
+
+ chain test {
+ ip protocol { tcp, udp } jump {
+ ip saddr vmap { 1.1.1.1 : jump z }
+ }
+ ip6 nexthdr { tcp, udp } ct mark and 2 == 2 counter
+ }
+}"
+
+$NFT -c -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT -f - <<< "$RULESET" >/dev/null || exit 0
+$NFT flush table inet filter || exit 0
diff --git a/tests/shell/testcases/transactions/30s-stress b/tests/shell/testcases/transactions/30s-stress
new file mode 100755
index 0000000..4c3c6a2
--- /dev/null
+++ b/tests/shell/testcases/transactions/30s-stress
@@ -0,0 +1,637 @@
+#!/bin/bash
+
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+
+runtime=30
+
+# allow stand-alone execution as well, e.g. '$0 3600'
+if [ x"$1" != "x" ] ;then
+ if [ $1 -ge 0 ]; then
+ runtime="$1"
+ else
+ echo "Invalid runtime $1"
+ exit 1
+ fi
+fi
+
+if [ x = x"$NFT" ] ; then
+ NFT=nft
+fi
+
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Skip it. You may ensure that the limits are suitable and rerun
+ # with NFT_TEST_HAS_SOCKET_LIMITS=n.
+ exit 77
+fi
+
+if [ -z "${NFT_TEST_HAVE_chain_binding+x}" ] ; then
+ NFT_TEST_HAVE_chain_binding=n
+ mydir="$(dirname "$0")"
+ $NFT --check -f "$mydir/../../features/chain_binding.nft"
+ if [ $? -eq 0 ];then
+ NFT_TEST_HAVE_chain_binding=y
+ else
+ echo "Assuming anonymous chains are not supported"
+ fi
+fi
+
+testns=testns-$(mktemp -u "XXXXXXXX")
+tmp=""
+
+faultname="/proc/self/make-it-fail"
+tables="foo bar"
+
+failslab_defaults() {
+ test -w $faultname || return
+
+ # Disable fault injection unless process has 'make-it-fail' set
+ echo Y > /sys/kernel/debug/failslab/task-filter
+
+ # allow all slabs to fail (if process is tagged).
+ find /sys/kernel/slab/ -wholename '*/kmalloc-[0-9]*/failslab' -type f -exec sh -c 'echo 1 > {}' \;
+
+ # no limit on the number of failures, or clause works around old kernels that reject negative integer.
+ echo -1 > /sys/kernel/debug/failslab/times 2>/dev/null || printf '%#x -1' > /sys/kernel/debug/failslab/times
+
+ # Set to 2 for full dmesg traces for each injected error
+ echo 0 > /sys/kernel/debug/failslab/verbose
+}
+
+failslab_random()
+{
+ r=$((RANDOM%2))
+
+ if [ $r -eq 0 ]; then
+ echo Y > /sys/kernel/debug/failslab/ignore-gfp-wait
+ else
+ echo N > /sys/kernel/debug/failslab/ignore-gfp-wait
+ fi
+
+ r=$((RANDOM%5))
+ echo $r > /sys/kernel/debug/failslab/probability
+ r=$((RANDOM%100))
+ echo $r > /sys/kernel/debug/failslab/interval
+
+ # allow a small initial 'success budget'.
+ # failures only appear after this many allocated bytes.
+ r=$((RANDOM%16384))
+ echo $r > /sys/kernel/debug/$FAILTYPE/space
+}
+
+netns_del() {
+ ip netns pids "$testns" | xargs kill 2>/dev/null
+ ip netns del "$testns"
+}
+
+netns_add()
+{
+ ip netns add "$testns"
+ ip -netns "$testns" link set lo up
+}
+
+cleanup() {
+ [ "$tmp" = "" ] || rm -f "$tmp"
+ netns_del
+}
+
+nft_with_fault_inject()
+{
+ file="$1"
+
+ if [ -w "$faultname" ]; then
+ failslab_random
+
+ ip netns exec "$testns" bash -c "echo 1 > $faultname ; exec $NFT -f $file"
+ fi
+
+ ip netns exec "$testns" $NFT -f "$file"
+}
+
+trap cleanup EXIT
+tmp=$(mktemp)
+
+jump_or_goto()
+{
+ if [ $((RANDOM & 1)) -eq 0 ] ;then
+ echo -n "jump"
+ else
+ echo -n "goto"
+ fi
+}
+
+random_verdict()
+{
+ max="$1"
+
+ if [ $max -eq 0 ]; then
+ max=1
+ fi
+
+ rnd=$((RANDOM%max))
+
+ if [ $rnd -gt 0 ];then
+ jump_or_goto
+ printf " chain%03u" "$((rnd+1))"
+ return
+ fi
+
+ if [ $((RANDOM & 1)) -eq 0 ] ;then
+ echo "accept"
+ else
+ echo "drop"
+ fi
+}
+
+randsleep()
+{
+ local s=$((RANDOM%1))
+ local ms=$((RANDOM%1000))
+ sleep $s.$ms
+}
+
+randlist()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ ip netns exec $testns $NFT list ruleset > /dev/null
+ done
+}
+
+randflush()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ ip netns exec $testns $NFT flush ruleset > /dev/null
+ done
+}
+
+randdeltable()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ for t in $tables; do
+ r=$((RANDOM%10))
+
+ if [ $r -eq 1 ] ;then
+ ip netns exec $testns $NFT delete table inet $t
+ randsleep
+ fi
+ done
+ done
+}
+
+randdelset()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ for t in $tables; do
+ r=$((RANDOM%10))
+ s=$((RANDOM%10))
+
+ case $r in
+ 0)
+ setname=set_$s
+ ;;
+ 1)
+ setname=sett${s}
+ ;;
+ 2)
+ setname=dmap_${s}
+ ;;
+ 3)
+ setname=dmapt${s}
+ ;;
+ 4)
+ setname=vmap_${s}
+ ;;
+ 5)
+ setname=vmapt${s}
+ ;;
+ *)
+ continue
+ ;;
+ esac
+
+ if [ $r -eq 1 ] ;then
+ ip netns exec $testns $NFT delete set inet $t $setname
+ fi
+ done
+ done
+}
+
+randdelchain()
+{
+ while [ -r $tmp ]; do
+ for t in $tables; do
+ local c=$((RANDOM%100))
+ randsleep
+ chain=$(printf "chain%03u" "$c")
+
+ local r=$((RANDOM%10))
+ if [ $r -eq 1 ];then
+ # chain can be invalid/unknown.
+ ip netns exec $testns $NFT delete chain inet $t $chain
+ fi
+ done
+ done
+}
+
+randdisable()
+{
+ while [ -r $tmp ]; do
+ for t in $tables; do
+ randsleep
+ local r=$((RANDOM%10))
+ if [ $r -eq 1 ];then
+ ip netns exec $testns $NFT add table inet $t '{flags dormant; }'
+ randsleep
+ ip netns exec $testns $NFT add table inet $t '{ }'
+ fi
+ done
+ done
+}
+
+randdelns()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ netns_del
+ netns_add
+ randsleep
+ done
+}
+
+random_element_string=""
+
+# create a random element. Could cause any of the following:
+# 1. Invalid set/map
+# 2. Element already exists in set/map w. create
+# 3. Element is new but wants to jump to unknown chain
+# 4. Element already exsists in set/map w. add, but verdict (map data) differs
+# 5. Element is created/added/deleted from 'flags constant' set.
+random_elem()
+{
+ tr=$((RANDOM%2))
+ t=0
+
+ for table in $tables; do
+ if [ $t -ne $tr ]; then
+ t=$((t+1))
+ continue
+ fi
+
+ kr=$((RANDOM%2))
+ k=0
+ cnt=0
+ for key in "single" "concat"; do
+ if [ $k -ne $kr ] ;then
+ cnt=$((cnt+2))
+ k=$((k+1))
+ continue
+ fi
+
+ fr=$((RANDOM%2))
+ f=0
+ for flags in "" "interval" ; do
+ cnt=$((cnt+1))
+ if [ $f -ne fkr ] ;then
+ f=$((f+1))
+ continue
+ fi
+
+ want="${key}${flags}"
+
+ e=$((RANDOM%256))
+ case "$want" in
+ "single") element="10.1.1.$e"
+ ;;
+ "concat") element="10.1.2.$e . $((RANDOM%65536))"
+ ;;
+ "singleinterval") element="10.1.$e.0-10.1.$e.$e"
+ ;;
+ "concatinterval") element="10.1.$e.0-10.1.$e.$e . $((RANDOM%65536))"
+ ;;
+ *) echo "bogus key $want"
+ exit 111
+ ;;
+ esac
+
+ # This may result in invalid jump, but thats what we want.
+ count=$(($RANDOM%100))
+
+ r=$((RANDOM%7))
+ case "$r" in
+ 0)
+ random_element_string=" inet $table set_${cnt} { $element }"
+ ;;
+ 1) random_element_string="inet $table sett${cnt} { $element timeout $((RANDOM%60))s }"
+ ;;
+ 2) random_element_string="inet $table dmap_${cnt} { $element : $RANDOM }"
+ ;;
+ 3) random_element_string="inet $table dmapt${cnt} { $element timeout $((RANDOM%60))s : $RANDOM }"
+ ;;
+ 4) random_element_string="inet $table vmap_${cnt} { $element : `random_verdict $count` }"
+ ;;
+ 5) random_element_string="inet $table vmapt${cnt} { $element timeout $((RANDOM%60))s : `random_verdict $count` }"
+ ;;
+ 6) random_element_string="inet $table setc${cnt} { $element }"
+ ;;
+ esac
+
+ return
+ done
+ done
+ done
+}
+
+randload()
+{
+ while [ -r $tmp ]; do
+ random_element_string=""
+ r=$((RANDOM%10))
+
+ what=""
+ case $r in
+ 1)
+ (echo "flush ruleset"; cat "$tmp"
+ echo "insert rule inet foo INPUT meta nftrace set 1"
+ echo "insert rule inet foo OUTPUT meta nftrace set 1"
+ ) | nft_with_fault_inject "/dev/stdin"
+ ;;
+ 2) what="add"
+ ;;
+ 3) what="create"
+ ;;
+ 4) what="delete"
+ ;;
+ 5) what="destroy"
+ ;;
+ 6) what="get"
+ ;;
+ *)
+ randsleep
+ ;;
+ esac
+
+ if [ x"$what" = "x" ]; then
+ nft_with_fault_inject "$tmp"
+ else
+ # This can trigger abort path, for various reasons:
+ # invalid set name
+ # key mismatches set specification (concat vs. single value)
+ # attempt to delete non-existent key
+ # attempt to create dupliacte key
+ # attempt to add duplicate key with non-matching value (data)
+ # attempt to add new uniqeue key with a jump to an unknown chain
+ random_elem
+ ( cat "$tmp"; echo "$what element $random_element_string") | nft_with_fault_inject "/dev/stdin"
+ fi
+ done
+}
+
+randmonitor()
+{
+ while [ -r $tmp ]; do
+ randsleep
+ timeout=$((RANDOM%16))
+ timeout $((timeout+1)) $NFT monitor > /dev/null
+ done
+}
+
+floodping() {
+ cpunum=$(grep -c processor /proc/cpuinfo)
+ cpunum=$((cpunum+1))
+
+ while [ -r $tmp ]; do
+ spawn=$((RANDOM%$cpunum))
+
+ # spawn at most $cpunum processes. Or maybe none at all.
+ i=0
+ while [ $i -lt $spawn ]; do
+ mask=$(printf 0x%x $((1<<$i)))
+ timeout 3 ip netns exec "$testns" taskset $mask ping -4 -fq 127.0.0.1 > /dev/null &
+ timeout 3 ip netns exec "$testns" taskset $mask ping -6 -fq ::1 > /dev/null &
+ i=$((i+1))
+ done
+
+ wait
+ randsleep
+ done
+}
+
+stress_all()
+{
+ # if fault injection is enabled, first a quick test to trigger
+ # abort paths without any parallel deletes/flushes.
+ if [ -w $faultname ] ;then
+ for i in $(seq 1 10);do
+ nft_with_fault_inject "$tmp"
+ done
+ fi
+
+ randlist &
+ randflush &
+ randdeltable &
+ randdisable &
+ randdelchain &
+ randdelset &
+ randdelns &
+ randload &
+ randmonitor &
+}
+
+gen_anon_chain_jump()
+{
+ echo -n "insert rule inet $@ "
+ jump_or_goto
+
+ if [ "$NFT_TEST_HAVE_chain_binding" = n ] ; then
+ echo " defaultchain"
+ return
+ fi
+
+ echo -n " { "
+ jump_or_goto
+ echo " defaultchain; counter; }"
+}
+
+gen_ruleset() {
+echo > "$tmp"
+for table in $tables; do
+ count=$((RANDOM % 100))
+ if [ $count -lt 1 ];then
+ count=1
+ fi
+
+ echo add table inet "$table" >> "$tmp"
+ echo flush table inet "$table" >> "$tmp"
+
+ echo "add chain inet $table INPUT { type filter hook input priority 0; }" >> "$tmp"
+ echo "add chain inet $table OUTPUT { type filter hook output priority 0; }" >> "$tmp"
+ for c in $(seq 1 $count); do
+ chain=$(printf "chain%03u" "$c")
+ echo "add chain inet $table $chain" >> "$tmp"
+ done
+
+ echo "add chain inet $table defaultchain" >> "$tmp"
+
+ for c in $(seq 1 $count); do
+ chain=$(printf "chain%03u" "$c")
+ for BASE in INPUT OUTPUT; do
+ echo "add rule inet $table $BASE counter jump $chain" >> "$tmp"
+ done
+ if [ $((RANDOM%10)) -eq 1 ];then
+ echo "add rule inet $table $chain counter jump defaultchain" >> "$tmp"
+ else
+ echo "add rule inet $table $chain counter return" >> "$tmp"
+ fi
+ done
+
+ cnt=0
+
+ # add a few anonymous sets. rhashtable is convered by named sets below.
+ c=$((RANDOM%$count))
+ chain=$(printf "chain%03u" "$((c+1))")
+ echo "insert rule inet $table $chain tcp dport 22-26 ip saddr { 1.2.3.4, 5.6.7.8 } counter comment hash_fast" >> "$tmp"
+ echo "insert rule inet $table $chain ip6 saddr { ::1, dead::beef } counter" comment hash >> "$tmp"
+ echo "insert rule inet $table $chain ip saddr { 1.2.3.4 - 5.6.7.8, 127.0.0.1 } comment rbtree" >> "$tmp"
+ # bitmap 1byte, with anon chain jump
+ gen_anon_chain_jump "$table $chain ip protocol { 6, 17 }" >> "$tmp"
+
+ # bitmap 2byte
+ echo "insert rule inet $table $chain tcp dport != { 22, 23, 80 } goto defaultchain" >> "$tmp"
+ echo "insert rule inet $table $chain tcp dport { 1-1024, 8000-8080 } jump defaultchain comment rbtree" >> "$tmp"
+ # pipapo (concat + set), with goto anonymous chain.
+ gen_anon_chain_jump "$table $chain ip saddr . tcp dport { 1.2.3.4 . 1-1024, 1.2.3.6 - 1.2.3.10 . 8000-8080, 1.2.3.4 . 8080, 1.2.3.6 - 1.2.3.10 . 22 }" >> "$tmp"
+
+ # add a few anonymous sets. rhashtable is convered by named sets below.
+ c=$((RANDOM%$count))
+ chain=$(printf "chain%03u" "$((c+1))")
+ echo "insert rule inet $table $chain tcp dport 22-26 ip saddr { 1.2.3.4, 5.6.7.8 } counter comment hash_fast" >> "$tmp"
+ echo "insert rule inet $table $chain ip6 saddr { ::1, dead::beef } counter" comment hash >> "$tmp"
+ echo "insert rule inet $table $chain ip saddr { 1.2.3.4 - 5.6.7.8, 127.0.0.1 } comment rbtree" >> "$tmp"
+ # bitmap 1byte, with anon chain jump
+ gen_anon_chain_jump "$table $chain ip protocol { 6, 17 }" >> "$tmp"
+ # bitmap 2byte
+ echo "insert rule inet $table $chain tcp dport != { 22, 23, 80 } goto defaultchain" >> "$tmp"
+ echo "insert rule inet $table $chain tcp dport { 1-1024, 8000-8080 } jump defaultchain comment rbtree" >> "$tmp"
+ # pipapo (concat + set), with goto anonymous chain.
+ gen_anon_chain_jump "$table $chain ip saddr . tcp dport { 1.2.3.4 . 1-1024, 1.2.3.6 - 1.2.3.10 . 8000-8080, 1.2.3.4 . 8080, 1.2.3.6 - 1.2.3.10 . 22 }" >> "$tmp"
+
+ # add constant/immutable sets
+ size=$((RANDOM%5120000))
+ size=$((size+2))
+ echo "add set inet $table setc1 { typeof tcp dport; size $size; flags constant; elements = { 22, 44 } }" >> "$tmp"
+ echo "add set inet $table setc2 { typeof ip saddr; size $size; flags constant; elements = { 1.2.3.4, 5.6.7.8 } }" >> "$tmp"
+ echo "add set inet $table setc3 { typeof ip6 daddr; size $size; flags constant; elements = { ::1, dead::1 } }" >> "$tmp"
+ echo "add set inet $table setc4 { typeof tcp dport; size $size; flags interval,constant; elements = { 22-44, 55-66 } }" >> "$tmp"
+ echo "add set inet $table setc5 { typeof ip saddr; size $size; flags interval,constant; elements = { 1.2.3.4-5.6.7.8, 10.1.1.1 } }" >> "$tmp"
+ echo "add set inet $table setc6 { typeof ip6 daddr; size $size; flags interval,constant; elements = { ::1, dead::1-dead::3 } }" >> "$tmp"
+
+ # add named sets with various combinations (plain value, range, concatenated values, concatenated ranges, with timeouts, with data ...)
+ for key in "ip saddr" "ip saddr . tcp dport"; do
+ for flags in "" "flags interval;" ; do
+ timeout=$((RANDOM%10))
+ timeout=$((timeout+1))
+ timeout="timeout ${timeout}s"
+
+ cnt=$((cnt+1))
+ echo "add set inet $table set_${cnt} { typeof ${key} ; ${flags} }" >> "$tmp"
+ echo "add set inet $table sett${cnt} { typeof ${key} ; $timeout; ${flags} }" >> "$tmp"
+ echo "add map inet $table dmap_${cnt} { typeof ${key} : meta mark ; ${flags} }" >> "$tmp"
+ echo "add map inet $table dmapt${cnt} { typeof ${key} : meta mark ; $timeout ; ${flags} }" >> "$tmp"
+ echo "add map inet $table vmap_${cnt} { typeof ${key} : verdict ; ${flags} }" >> "$tmp"
+ echo "add map inet $table vmapt${cnt} { typeof ${key} : verdict; $timeout ; ${flags} }" >> "$tmp"
+ done
+ done
+
+ cnt=0
+ for key in "single" "concat"; do
+ for flags in "" "interval" ; do
+ want="${key}${flags}"
+ cnt=$((cnt+1))
+ maxip=$((RANDOM%256))
+
+ if [ $maxip -eq 0 ];then
+ maxip=1
+ fi
+
+ for e in $(seq 1 $maxip);do
+ case "$want" in
+ "single") element="10.1.1.$e"
+ ;;
+ "concat")
+ element="10.1.2.$e . $((RANDOM%65536))"
+ ;;
+ "singleinterval")
+ element="10.1.$e.0-10.1.$e.$e"
+ ;;
+ "concatinterval")
+ element="10.1.$e.0-10.1.$e.$e . $((RANDOM%65536))"
+ ;;
+ *)
+ echo "bogus key $want"
+ exit 111
+ ;;
+ esac
+
+ echo "add element inet $table set_${cnt} { $element }" >> "$tmp"
+ echo "add element inet $table sett${cnt} { $element timeout $((RANDOM%60))s }" >> "$tmp"
+ echo "add element inet $table dmap_${cnt} { $element : $RANDOM }" >> "$tmp"
+ echo "add element inet $table dmapt${cnt} { $element timeout $((RANDOM%60))s : $RANDOM }" >> "$tmp"
+ echo "add element inet $table vmap_${cnt} { $element : `random_verdict $count` }" >> "$tmp"
+ echo "add element inet $table vmapt${cnt} { $element timeout $((RANDOM%60))s : `random_verdict $count` }" >> "$tmp"
+ done
+ done
+ done
+done
+}
+
+run_test()
+{
+ local time_now=$(date +%s)
+ local time_stop=$((time_now + $runtime))
+ local regen=30
+
+ while [ $time_now -lt $time_stop ]; do
+ if [ $regen -gt 0 ];then
+ sleep 1
+ time_now=$(date +%s)
+ regen=$((regen-1))
+ continue
+ fi
+
+ # This clobbers the previously generated ruleset, this is intentional.
+ gen_ruleset
+ regen=$((RANDOM%60))
+ regen=$((regen+2))
+ time_now=$(date +%s)
+ done
+}
+
+netns_add
+
+gen_ruleset
+ip netns exec "$testns" $NFT -f "$tmp" || exit 1
+
+failslab_defaults
+
+stress_all 2>/dev/null &
+
+randsleep
+
+floodping 2> /dev/null &
+
+run_test
+
+# this stops stress_all
+rm -f "$tmp"
+tmp=""
+sleep 4
+
+if [ "$NFT_TEST_HAVE_chain_binding" = n ] ; then
+ echo "Ran a modified version of the test due to NFT_TEST_HAVE_chain_binding=n"
+fi
diff --git a/tests/shell/testcases/transactions/anon_chain_loop b/tests/shell/testcases/transactions/anon_chain_loop
new file mode 100755
index 0000000..2fd6181
--- /dev/null
+++ b/tests/shell/testcases/transactions/anon_chain_loop
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# anon chains with c1 -> c2 recursive jump, expect failure
+$NFT -f - <<EOF
+table ip t {
+ chain c2 { }
+ chain c1 { }
+}
+
+add t c1 ip saddr 127.0.0.1 jump { jump c2; }
+add t c2 ip saddr 127.0.0.1 jump { jump c1; }
+EOF
+
+if [ $? -eq 0 ] ; then
+ echo "E: able to load bad ruleset" >&2
+ exit 1
+fi
+
+exit 0
diff --git a/tests/shell/testcases/transactions/bad_expression b/tests/shell/testcases/transactions/bad_expression
new file mode 100755
index 0000000..794b625
--- /dev/null
+++ b/tests/shell/testcases/transactions/bad_expression
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# table with invalid expression (masquerade called from filter table).
+# nft must return an error. Also catch nfnetlink retry loops that
+# cause nft or kernel to spin.
+timeout 3 $NFT -f - <<EOF
+table ip t0 {
+ chain c { }
+ chain input {
+ type filter hook input priority 0;
+ jump c
+ }
+}
+
+table ip t1 {
+ chain a {
+ masquerade
+ }
+ chain input {
+ type filter hook input priority 1;
+ jump a
+ }
+}
+EOF
+
+rc=$?
+if [ $rc -eq 0 ]; then
+ echo "Ruleset should have failed" 1>&2
+ exit 111
+fi
+
+# 124 means 'command timed out', fail if this
+# happens. Else, pass, failure is wanted here.
+if [ $rc -ne 124 ]; then
+ exit 0
+fi
+
+exit $rc
diff --git a/tests/shell/testcases/transactions/dumps/0001table_0.nft b/tests/shell/testcases/transactions/dumps/0001table_0.nft
new file mode 100644
index 0000000..e4e5f9b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0001table_0.nft
@@ -0,0 +1,4 @@
+table ip x {
+}
+table ip y {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0002table_0.nft b/tests/shell/testcases/transactions/dumps/0002table_0.nft
new file mode 100644
index 0000000..429cbc3
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0002table_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ flags dormant
+
+ chain y {
+ type nat hook prerouting priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0003table_0.nft b/tests/shell/testcases/transactions/dumps/0003table_0.nft
new file mode 100644
index 0000000..e4e5f9b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0003table_0.nft
@@ -0,0 +1,4 @@
+table ip x {
+}
+table ip y {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0010chain_0.nft b/tests/shell/testcases/transactions/dumps/0010chain_0.nft
new file mode 100644
index 0000000..aa4a521
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0010chain_0.nft
@@ -0,0 +1,4 @@
+table ip w {
+ chain y {
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0011chain_0.nft b/tests/shell/testcases/transactions/dumps/0011chain_0.nft
new file mode 100644
index 0000000..df88ad4
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0011chain_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ chain y {
+ type filter hook input priority filter; policy drop;
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0012chain_0.nft b/tests/shell/testcases/transactions/dumps/0012chain_0.nft
new file mode 100644
index 0000000..b9f5e43
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0012chain_0.nft
@@ -0,0 +1,5 @@
+table ip w {
+ chain y {
+ type filter hook output priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0013chain_0.nft b/tests/shell/testcases/transactions/dumps/0013chain_0.nft
new file mode 100644
index 0000000..b9f5e43
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0013chain_0.nft
@@ -0,0 +1,5 @@
+table ip w {
+ chain y {
+ type filter hook output priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0014chain_1.nft b/tests/shell/testcases/transactions/dumps/0014chain_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0014chain_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0015chain_0.nft b/tests/shell/testcases/transactions/dumps/0015chain_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0015chain_0.nft
diff --git a/tests/shell/testcases/transactions/dumps/0020rule_0.nft b/tests/shell/testcases/transactions/dumps/0020rule_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0020rule_0.nft
diff --git a/tests/shell/testcases/transactions/dumps/0021rule_0.nft b/tests/shell/testcases/transactions/dumps/0021rule_0.nft
new file mode 100644
index 0000000..a6c4130
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0021rule_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ chain y {
+ ip saddr 2.2.2.2 counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0022rule_1.nft b/tests/shell/testcases/transactions/dumps/0022rule_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0022rule_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0023rule_1.nft b/tests/shell/testcases/transactions/dumps/0023rule_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0023rule_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0024rule_0.nft b/tests/shell/testcases/transactions/dumps/0024rule_0.nft
new file mode 100644
index 0000000..7860ff6
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0024rule_0.nft
@@ -0,0 +1,8 @@
+table ip x {
+ chain y {
+ accept comment "rule1"
+ accept comment "rule2"
+ accept comment "rule3"
+ accept comment "rule4"
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0025rule_0.nft b/tests/shell/testcases/transactions/dumps/0025rule_0.nft
new file mode 100644
index 0000000..dcb61ae
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0025rule_0.nft
@@ -0,0 +1,6 @@
+table ip x {
+ chain y {
+ log
+ drop
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0030set_0.nft b/tests/shell/testcases/transactions/dumps/0030set_0.nft
new file mode 100644
index 0000000..5d4d2ca
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0030set_0.nft
@@ -0,0 +1,2 @@
+table ip x {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0031set_0.nft b/tests/shell/testcases/transactions/dumps/0031set_0.nft
new file mode 100644
index 0000000..e3d4aee
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0031set_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0032set_0.nft b/tests/shell/testcases/transactions/dumps/0032set_0.nft
new file mode 100644
index 0000000..7d11892
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0032set_0.nft
@@ -0,0 +1,5 @@
+table ip w {
+ set y {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0033set_0.nft b/tests/shell/testcases/transactions/dumps/0033set_0.nft
new file mode 100644
index 0000000..5d4d2ca
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0033set_0.nft
@@ -0,0 +1,2 @@
+table ip x {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0034set_0.nft b/tests/shell/testcases/transactions/dumps/0034set_0.nft
new file mode 100644
index 0000000..e3d4aee
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0034set_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0035set_0.nft b/tests/shell/testcases/transactions/dumps/0035set_0.nft
new file mode 100644
index 0000000..e111494
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0035set_0.nft
@@ -0,0 +1,6 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ elements = { 3.3.3.3 }
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0036set_1.nft b/tests/shell/testcases/transactions/dumps/0036set_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0036set_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0037set_0.nft b/tests/shell/testcases/transactions/dumps/0037set_0.nft
new file mode 100644
index 0000000..ca69cee
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0037set_0.nft
@@ -0,0 +1,6 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0038set_0.nft b/tests/shell/testcases/transactions/dumps/0038set_0.nft
new file mode 100644
index 0000000..651a11b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0038set_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.4.0/24 }
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0039set_0.nft b/tests/shell/testcases/transactions/dumps/0039set_0.nft
new file mode 100644
index 0000000..651a11b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0039set_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.4.0/24 }
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0040set_0.nft b/tests/shell/testcases/transactions/dumps/0040set_0.nft
new file mode 100644
index 0000000..a29232b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0040set_0.nft
@@ -0,0 +1,14 @@
+table ip filter {
+ map client_to_any {
+ type ipv4_addr : verdict
+ }
+
+ chain FORWARD {
+ type filter hook forward priority filter; policy accept;
+ goto client_to_any
+ }
+
+ chain client_to_any {
+ ip saddr vmap @client_to_any
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0041nat_restore_0.nft b/tests/shell/testcases/transactions/dumps/0041nat_restore_0.nft
new file mode 100644
index 0000000..b718001
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0041nat_restore_0.nft
@@ -0,0 +1,5 @@
+table ip t {
+ chain c {
+ type nat hook postrouting priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0042_stateful_expr_0.nft b/tests/shell/testcases/transactions/dumps/0042_stateful_expr_0.nft
new file mode 100644
index 0000000..e5cc63f
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0042_stateful_expr_0.nft
@@ -0,0 +1,5 @@
+table ip filter {
+ map m1 {
+ type ipv4_addr : counter
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0043set_1.nft b/tests/shell/testcases/transactions/dumps/0043set_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0043set_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0044rule_0.nft b/tests/shell/testcases/transactions/dumps/0044rule_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0044rule_0.nft
diff --git a/tests/shell/testcases/transactions/dumps/0045anon-unbind_0.nft b/tests/shell/testcases/transactions/dumps/0045anon-unbind_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0045anon-unbind_0.nft
diff --git a/tests/shell/testcases/transactions/dumps/0046set_0.nft b/tests/shell/testcases/transactions/dumps/0046set_0.nft
new file mode 100644
index 0000000..eb39c44
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0046set_0.nft
@@ -0,0 +1,2 @@
+table ip filter {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0047set_0.nft b/tests/shell/testcases/transactions/dumps/0047set_0.nft
new file mode 100644
index 0000000..4da397b
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0047set_0.nft
@@ -0,0 +1,11 @@
+table ip filter {
+ map group_10060 {
+ type ipv4_addr : classid
+ flags interval
+ elements = { 10.1.26.2 : 1:bbf8, 10.1.26.3 : 1:c1ad,
+ 10.1.26.4 : 1:b2d7, 10.1.26.5 : 1:f705,
+ 10.1.26.6 : 1:b895, 10.1.26.7 : 1:ec4c,
+ 10.1.26.8 : 1:de78, 10.1.26.9 : 1:b4f3,
+ 10.1.26.10 : 1:dec6, 10.1.26.11 : 1:b4c0 }
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0048helpers_0.nft b/tests/shell/testcases/transactions/dumps/0048helpers_0.nft
new file mode 100644
index 0000000..eb39c44
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0048helpers_0.nft
@@ -0,0 +1,2 @@
+table ip filter {
+}
diff --git a/tests/shell/testcases/transactions/dumps/0049huge_0.nft b/tests/shell/testcases/transactions/dumps/0049huge_0.nft
new file mode 100644
index 0000000..96f5a38
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0049huge_0.nft
@@ -0,0 +1,749 @@
+table inet firewalld {
+ chain raw_PREROUTING {
+ type filter hook prerouting priority raw + 10; policy accept;
+ icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept
+ meta nfproto ipv6 fib saddr . iif oif missing drop
+ jump raw_PREROUTING_ZONES
+ }
+
+ chain raw_PREROUTING_ZONES {
+ iifname "perm_dummy" goto raw_PRE_work
+ iifname "perm_dummy2" goto raw_PRE_trusted
+ goto raw_PRE_public
+ }
+
+ chain mangle_PREROUTING {
+ type filter hook prerouting priority mangle + 10; policy accept;
+ jump mangle_PREROUTING_ZONES
+ }
+
+ chain mangle_PREROUTING_ZONES {
+ iifname "perm_dummy" goto mangle_PRE_work
+ iifname "perm_dummy2" goto mangle_PRE_trusted
+ goto mangle_PRE_public
+ }
+
+ chain filter_INPUT {
+ type filter hook input priority filter + 10; policy accept;
+ ct state { established, related } accept
+ ct status dnat accept
+ iifname "lo" accept
+ jump filter_INPUT_ZONES
+ ct state invalid drop
+ reject with icmpx admin-prohibited
+ }
+
+ chain filter_FORWARD {
+ type filter hook forward priority filter + 10; policy accept;
+ ct state { established, related } accept
+ ct status dnat accept
+ iifname "lo" accept
+ ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 addr-unreachable
+ jump filter_FORWARD_IN_ZONES
+ jump filter_FORWARD_OUT_ZONES
+ ct state invalid drop
+ reject with icmpx admin-prohibited
+ }
+
+ chain filter_OUTPUT {
+ type filter hook output priority filter + 10; policy accept;
+ oifname "lo" accept
+ ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 addr-unreachable
+ }
+
+ chain filter_INPUT_ZONES {
+ iifname "perm_dummy" goto filter_IN_work
+ iifname "perm_dummy2" goto filter_IN_trusted
+ goto filter_IN_public
+ }
+
+ chain filter_FORWARD_IN_ZONES {
+ iifname "perm_dummy" goto filter_FWDI_work
+ iifname "perm_dummy2" goto filter_FWDI_trusted
+ goto filter_FWDI_public
+ }
+
+ chain filter_FORWARD_OUT_ZONES {
+ oifname "perm_dummy" goto filter_FWDO_work
+ oifname "perm_dummy2" goto filter_FWDO_trusted
+ goto filter_FWDO_public
+ }
+
+ chain raw_PRE_public {
+ jump raw_PRE_public_pre
+ jump raw_PRE_public_log
+ jump raw_PRE_public_deny
+ jump raw_PRE_public_allow
+ jump raw_PRE_public_post
+ }
+
+ chain raw_PRE_public_pre {
+ }
+
+ chain raw_PRE_public_log {
+ }
+
+ chain raw_PRE_public_deny {
+ }
+
+ chain raw_PRE_public_allow {
+ }
+
+ chain raw_PRE_public_post {
+ }
+
+ chain filter_IN_public {
+ jump filter_IN_public_pre
+ jump filter_IN_public_log
+ jump filter_IN_public_deny
+ jump filter_IN_public_allow
+ jump filter_IN_public_post
+ meta l4proto { icmp, ipv6-icmp } accept
+ }
+
+ chain filter_IN_public_pre {
+ }
+
+ chain filter_IN_public_log {
+ }
+
+ chain filter_IN_public_deny {
+ }
+
+ chain filter_IN_public_allow {
+ tcp dport 22 ct state { new, untracked } accept
+ ip6 daddr fe80::/64 udp dport 546 ct state { new, untracked } accept
+ }
+
+ chain filter_IN_public_post {
+ }
+
+ chain filter_FWDI_public {
+ jump filter_FWDI_public_pre
+ jump filter_FWDI_public_log
+ jump filter_FWDI_public_deny
+ jump filter_FWDI_public_allow
+ jump filter_FWDI_public_post
+ meta l4proto { icmp, ipv6-icmp } accept
+ }
+
+ chain filter_FWDI_public_pre {
+ }
+
+ chain filter_FWDI_public_log {
+ }
+
+ chain filter_FWDI_public_deny {
+ }
+
+ chain filter_FWDI_public_allow {
+ }
+
+ chain filter_FWDI_public_post {
+ }
+
+ chain mangle_PRE_public {
+ jump mangle_PRE_public_pre
+ jump mangle_PRE_public_log
+ jump mangle_PRE_public_deny
+ jump mangle_PRE_public_allow
+ jump mangle_PRE_public_post
+ }
+
+ chain mangle_PRE_public_pre {
+ }
+
+ chain mangle_PRE_public_log {
+ }
+
+ chain mangle_PRE_public_deny {
+ }
+
+ chain mangle_PRE_public_allow {
+ }
+
+ chain mangle_PRE_public_post {
+ }
+
+ chain filter_FWDO_public {
+ jump filter_FWDO_public_pre
+ jump filter_FWDO_public_log
+ jump filter_FWDO_public_deny
+ jump filter_FWDO_public_allow
+ jump filter_FWDO_public_post
+ }
+
+ chain filter_FWDO_public_pre {
+ }
+
+ chain filter_FWDO_public_log {
+ }
+
+ chain filter_FWDO_public_deny {
+ }
+
+ chain filter_FWDO_public_allow {
+ }
+
+ chain filter_FWDO_public_post {
+ }
+
+ chain raw_PRE_trusted {
+ jump raw_PRE_trusted_pre
+ jump raw_PRE_trusted_log
+ jump raw_PRE_trusted_deny
+ jump raw_PRE_trusted_allow
+ jump raw_PRE_trusted_post
+ }
+
+ chain raw_PRE_trusted_pre {
+ }
+
+ chain raw_PRE_trusted_log {
+ }
+
+ chain raw_PRE_trusted_deny {
+ }
+
+ chain raw_PRE_trusted_allow {
+ }
+
+ chain raw_PRE_trusted_post {
+ }
+
+ chain mangle_PRE_trusted {
+ jump mangle_PRE_trusted_pre
+ jump mangle_PRE_trusted_log
+ jump mangle_PRE_trusted_deny
+ jump mangle_PRE_trusted_allow
+ jump mangle_PRE_trusted_post
+ }
+
+ chain mangle_PRE_trusted_pre {
+ }
+
+ chain mangle_PRE_trusted_log {
+ }
+
+ chain mangle_PRE_trusted_deny {
+ }
+
+ chain mangle_PRE_trusted_allow {
+ }
+
+ chain mangle_PRE_trusted_post {
+ }
+
+ chain filter_IN_trusted {
+ jump filter_IN_trusted_pre
+ jump filter_IN_trusted_log
+ jump filter_IN_trusted_deny
+ jump filter_IN_trusted_allow
+ jump filter_IN_trusted_post
+ accept
+ }
+
+ chain filter_IN_trusted_pre {
+ }
+
+ chain filter_IN_trusted_log {
+ }
+
+ chain filter_IN_trusted_deny {
+ }
+
+ chain filter_IN_trusted_allow {
+ }
+
+ chain filter_IN_trusted_post {
+ }
+
+ chain filter_FWDI_trusted {
+ jump filter_FWDI_trusted_pre
+ jump filter_FWDI_trusted_log
+ jump filter_FWDI_trusted_deny
+ jump filter_FWDI_trusted_allow
+ jump filter_FWDI_trusted_post
+ accept
+ }
+
+ chain filter_FWDI_trusted_pre {
+ }
+
+ chain filter_FWDI_trusted_log {
+ }
+
+ chain filter_FWDI_trusted_deny {
+ }
+
+ chain filter_FWDI_trusted_allow {
+ }
+
+ chain filter_FWDI_trusted_post {
+ }
+
+ chain filter_FWDO_trusted {
+ jump filter_FWDO_trusted_pre
+ jump filter_FWDO_trusted_log
+ jump filter_FWDO_trusted_deny
+ jump filter_FWDO_trusted_allow
+ jump filter_FWDO_trusted_post
+ accept
+ }
+
+ chain filter_FWDO_trusted_pre {
+ }
+
+ chain filter_FWDO_trusted_log {
+ }
+
+ chain filter_FWDO_trusted_deny {
+ }
+
+ chain filter_FWDO_trusted_allow {
+ }
+
+ chain filter_FWDO_trusted_post {
+ }
+
+ chain raw_PRE_work {
+ jump raw_PRE_work_pre
+ jump raw_PRE_work_log
+ jump raw_PRE_work_deny
+ jump raw_PRE_work_allow
+ jump raw_PRE_work_post
+ }
+
+ chain raw_PRE_work_pre {
+ }
+
+ chain raw_PRE_work_log {
+ }
+
+ chain raw_PRE_work_deny {
+ }
+
+ chain raw_PRE_work_allow {
+ }
+
+ chain raw_PRE_work_post {
+ }
+
+ chain filter_IN_work {
+ jump filter_IN_work_pre
+ jump filter_IN_work_log
+ jump filter_IN_work_deny
+ jump filter_IN_work_allow
+ jump filter_IN_work_post
+ meta l4proto { icmp, ipv6-icmp } accept
+ }
+
+ chain filter_IN_work_pre {
+ }
+
+ chain filter_IN_work_log {
+ }
+
+ chain filter_IN_work_deny {
+ }
+
+ chain filter_IN_work_allow {
+ tcp dport 22 ct state { new, untracked } accept
+ ip6 daddr fe80::/64 udp dport 546 ct state { new, untracked } accept
+ }
+
+ chain filter_IN_work_post {
+ }
+
+ chain mangle_PRE_work {
+ jump mangle_PRE_work_pre
+ jump mangle_PRE_work_log
+ jump mangle_PRE_work_deny
+ jump mangle_PRE_work_allow
+ jump mangle_PRE_work_post
+ }
+
+ chain mangle_PRE_work_pre {
+ }
+
+ chain mangle_PRE_work_log {
+ }
+
+ chain mangle_PRE_work_deny {
+ }
+
+ chain mangle_PRE_work_allow {
+ }
+
+ chain mangle_PRE_work_post {
+ }
+
+ chain filter_FWDI_work {
+ jump filter_FWDI_work_pre
+ jump filter_FWDI_work_log
+ jump filter_FWDI_work_deny
+ jump filter_FWDI_work_allow
+ jump filter_FWDI_work_post
+ meta l4proto { icmp, ipv6-icmp } accept
+ }
+
+ chain filter_FWDI_work_pre {
+ }
+
+ chain filter_FWDI_work_log {
+ }
+
+ chain filter_FWDI_work_deny {
+ }
+
+ chain filter_FWDI_work_allow {
+ }
+
+ chain filter_FWDI_work_post {
+ }
+
+ chain filter_FWDO_work {
+ jump filter_FWDO_work_pre
+ jump filter_FWDO_work_log
+ jump filter_FWDO_work_deny
+ jump filter_FWDO_work_allow
+ jump filter_FWDO_work_post
+ }
+
+ chain filter_FWDO_work_pre {
+ }
+
+ chain filter_FWDO_work_log {
+ }
+
+ chain filter_FWDO_work_deny {
+ }
+
+ chain filter_FWDO_work_allow {
+ }
+
+ chain filter_FWDO_work_post {
+ }
+}
+table ip firewalld {
+ chain nat_PREROUTING {
+ type nat hook prerouting priority dstnat + 10; policy accept;
+ jump nat_PREROUTING_ZONES
+ }
+
+ chain nat_PREROUTING_ZONES {
+ iifname "perm_dummy" goto nat_PRE_work
+ iifname "perm_dummy2" goto nat_PRE_trusted
+ goto nat_PRE_public
+ }
+
+ chain nat_POSTROUTING {
+ type nat hook postrouting priority srcnat + 10; policy accept;
+ jump nat_POSTROUTING_ZONES
+ }
+
+ chain nat_POSTROUTING_ZONES {
+ oifname "perm_dummy" goto nat_POST_work
+ oifname "perm_dummy2" goto nat_POST_trusted
+ goto nat_POST_public
+ }
+
+ chain nat_PRE_public {
+ jump nat_PRE_public_pre
+ jump nat_PRE_public_log
+ jump nat_PRE_public_deny
+ jump nat_PRE_public_allow
+ jump nat_PRE_public_post
+ }
+
+ chain nat_PRE_public_pre {
+ }
+
+ chain nat_PRE_public_log {
+ }
+
+ chain nat_PRE_public_deny {
+ }
+
+ chain nat_PRE_public_allow {
+ }
+
+ chain nat_PRE_public_post {
+ }
+
+ chain nat_POST_public {
+ jump nat_POST_public_pre
+ jump nat_POST_public_log
+ jump nat_POST_public_deny
+ jump nat_POST_public_allow
+ jump nat_POST_public_post
+ }
+
+ chain nat_POST_public_pre {
+ }
+
+ chain nat_POST_public_log {
+ }
+
+ chain nat_POST_public_deny {
+ }
+
+ chain nat_POST_public_allow {
+ }
+
+ chain nat_POST_public_post {
+ }
+
+ chain nat_PRE_trusted {
+ jump nat_PRE_trusted_pre
+ jump nat_PRE_trusted_log
+ jump nat_PRE_trusted_deny
+ jump nat_PRE_trusted_allow
+ jump nat_PRE_trusted_post
+ }
+
+ chain nat_PRE_trusted_pre {
+ }
+
+ chain nat_PRE_trusted_log {
+ }
+
+ chain nat_PRE_trusted_deny {
+ }
+
+ chain nat_PRE_trusted_allow {
+ }
+
+ chain nat_PRE_trusted_post {
+ }
+
+ chain nat_POST_trusted {
+ jump nat_POST_trusted_pre
+ jump nat_POST_trusted_log
+ jump nat_POST_trusted_deny
+ jump nat_POST_trusted_allow
+ jump nat_POST_trusted_post
+ }
+
+ chain nat_POST_trusted_pre {
+ }
+
+ chain nat_POST_trusted_log {
+ }
+
+ chain nat_POST_trusted_deny {
+ }
+
+ chain nat_POST_trusted_allow {
+ }
+
+ chain nat_POST_trusted_post {
+ }
+
+ chain nat_PRE_work {
+ jump nat_PRE_work_pre
+ jump nat_PRE_work_log
+ jump nat_PRE_work_deny
+ jump nat_PRE_work_allow
+ jump nat_PRE_work_post
+ }
+
+ chain nat_PRE_work_pre {
+ }
+
+ chain nat_PRE_work_log {
+ }
+
+ chain nat_PRE_work_deny {
+ }
+
+ chain nat_PRE_work_allow {
+ }
+
+ chain nat_PRE_work_post {
+ }
+
+ chain nat_POST_work {
+ jump nat_POST_work_pre
+ jump nat_POST_work_log
+ jump nat_POST_work_deny
+ jump nat_POST_work_allow
+ jump nat_POST_work_post
+ }
+
+ chain nat_POST_work_pre {
+ }
+
+ chain nat_POST_work_log {
+ }
+
+ chain nat_POST_work_deny {
+ }
+
+ chain nat_POST_work_allow {
+ }
+
+ chain nat_POST_work_post {
+ }
+}
+table ip6 firewalld {
+ chain nat_PREROUTING {
+ type nat hook prerouting priority dstnat + 10; policy accept;
+ jump nat_PREROUTING_ZONES
+ }
+
+ chain nat_PREROUTING_ZONES {
+ iifname "perm_dummy" goto nat_PRE_work
+ iifname "perm_dummy2" goto nat_PRE_trusted
+ goto nat_PRE_public
+ }
+
+ chain nat_POSTROUTING {
+ type nat hook postrouting priority srcnat + 10; policy accept;
+ jump nat_POSTROUTING_ZONES
+ }
+
+ chain nat_POSTROUTING_ZONES {
+ oifname "perm_dummy" goto nat_POST_work
+ oifname "perm_dummy2" goto nat_POST_trusted
+ goto nat_POST_public
+ }
+
+ chain nat_PRE_public {
+ jump nat_PRE_public_pre
+ jump nat_PRE_public_log
+ jump nat_PRE_public_deny
+ jump nat_PRE_public_allow
+ jump nat_PRE_public_post
+ }
+
+ chain nat_PRE_public_pre {
+ }
+
+ chain nat_PRE_public_log {
+ }
+
+ chain nat_PRE_public_deny {
+ }
+
+ chain nat_PRE_public_allow {
+ }
+
+ chain nat_PRE_public_post {
+ }
+
+ chain nat_POST_public {
+ jump nat_POST_public_pre
+ jump nat_POST_public_log
+ jump nat_POST_public_deny
+ jump nat_POST_public_allow
+ jump nat_POST_public_post
+ }
+
+ chain nat_POST_public_pre {
+ }
+
+ chain nat_POST_public_log {
+ }
+
+ chain nat_POST_public_deny {
+ }
+
+ chain nat_POST_public_allow {
+ }
+
+ chain nat_POST_public_post {
+ }
+
+ chain nat_PRE_trusted {
+ jump nat_PRE_trusted_pre
+ jump nat_PRE_trusted_log
+ jump nat_PRE_trusted_deny
+ jump nat_PRE_trusted_allow
+ jump nat_PRE_trusted_post
+ }
+
+ chain nat_PRE_trusted_pre {
+ }
+
+ chain nat_PRE_trusted_log {
+ }
+
+ chain nat_PRE_trusted_deny {
+ }
+
+ chain nat_PRE_trusted_allow {
+ }
+
+ chain nat_PRE_trusted_post {
+ }
+
+ chain nat_POST_trusted {
+ jump nat_POST_trusted_pre
+ jump nat_POST_trusted_log
+ jump nat_POST_trusted_deny
+ jump nat_POST_trusted_allow
+ jump nat_POST_trusted_post
+ }
+
+ chain nat_POST_trusted_pre {
+ }
+
+ chain nat_POST_trusted_log {
+ }
+
+ chain nat_POST_trusted_deny {
+ }
+
+ chain nat_POST_trusted_allow {
+ }
+
+ chain nat_POST_trusted_post {
+ }
+
+ chain nat_PRE_work {
+ jump nat_PRE_work_pre
+ jump nat_PRE_work_log
+ jump nat_PRE_work_deny
+ jump nat_PRE_work_allow
+ jump nat_PRE_work_post
+ }
+
+ chain nat_PRE_work_pre {
+ }
+
+ chain nat_PRE_work_log {
+ }
+
+ chain nat_PRE_work_deny {
+ }
+
+ chain nat_PRE_work_allow {
+ }
+
+ chain nat_PRE_work_post {
+ }
+
+ chain nat_POST_work {
+ jump nat_POST_work_pre
+ jump nat_POST_work_log
+ jump nat_POST_work_deny
+ jump nat_POST_work_allow
+ jump nat_POST_work_post
+ }
+
+ chain nat_POST_work_pre {
+ }
+
+ chain nat_POST_work_log {
+ }
+
+ chain nat_POST_work_deny {
+ }
+
+ chain nat_POST_work_allow {
+ }
+
+ chain nat_POST_work_post {
+ }
+}
diff --git a/tests/shell/testcases/transactions/dumps/0050rule_1.nft b/tests/shell/testcases/transactions/dumps/0050rule_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0050rule_1.nft
diff --git a/tests/shell/testcases/transactions/dumps/0051map_0.nodump b/tests/shell/testcases/transactions/dumps/0051map_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/0051map_0.nodump
diff --git a/tests/shell/testcases/transactions/dumps/30s-stress.nft b/tests/shell/testcases/transactions/dumps/30s-stress.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/30s-stress.nft
diff --git a/tests/shell/testcases/transactions/dumps/anon_chain_loop.nft b/tests/shell/testcases/transactions/dumps/anon_chain_loop.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/anon_chain_loop.nft
diff --git a/tests/shell/testcases/transactions/dumps/bad_expression.nft b/tests/shell/testcases/transactions/dumps/bad_expression.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/bad_expression.nft
diff --git a/tests/shell/testcases/transactions/dumps/table_onoff.nft b/tests/shell/testcases/transactions/dumps/table_onoff.nft
new file mode 100644
index 0000000..038be1c
--- /dev/null
+++ b/tests/shell/testcases/transactions/dumps/table_onoff.nft
@@ -0,0 +1,8 @@
+table ip t {
+ flags dormant
+
+ chain c {
+ type filter hook input priority filter; policy accept;
+ ip daddr 127.0.0.42 counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/transactions/table_onoff b/tests/shell/testcases/transactions/table_onoff
new file mode 100755
index 0000000..831d461
--- /dev/null
+++ b/tests/shell/testcases/transactions/table_onoff
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# attempt to re-awaken a table that is flagged dormant within
+# same transaction
+$NFT -f - <<EOF
+add table ip t
+add table ip t { flags dormant; }
+add chain ip t c { type filter hook input priority 0; }
+add table ip t
+delete table ip t
+EOF
+
+if [ $? -eq 0 ]; then
+ exit 1
+fi
+
+set -e
+
+ip link set lo up
+
+# add a dormant table, then wake it up in same
+# transaction.
+$NFT -f - <<EOF
+add table ip t { flags dormant; }
+add chain ip t c { type filter hook input priority 0; }
+add rule ip t c ip daddr 127.0.0.42 counter
+add table ip t
+EOF
+
+# check table is indeed active.
+ping -c 1 127.0.0.42
+$NFT list chain ip t c | grep "counter packets 1"
+$NFT delete table ip t
+
+# allow to flag table dormant.
+$NFT -f - <<EOF
+add table ip t
+add chain ip t c { type filter hook input priority 0; }
+add rule ip t c ip daddr 127.0.0.42 counter
+add table ip t { flags dormant; }
+EOF
+
+ping -c 1 127.0.0.42
+# expect run-tests.sh to complain if counter isn't 0.