mirror of
https://git.netfilter.org/nftables
synced 2026-01-26 02:27:52 +00:00
tests: shell: add JSON test for handle-based rule positioning
Add comprehensive test for JSON handle-based rule positioning to verify the handle field correctly positions rules with explicit add/insert commands while being ignored in implicit format. Test coverage: 1. ADD with handle positions AFTER the specified handle 2. INSERT with handle positions BEFORE the specified handle 3. INSERT without handle positions at beginning 4. Multiple commands in single transaction (batch behavior) 5. Implicit format ignores handle field for portability The test uses sed for handle extraction and nft -f format for setup as suggested in code review. Final state is a table with two rules from the implicit format test. Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
This commit is contained in:
parent
72db5e53f3
commit
7e7c152fc8
162
tests/shell/testcases/json/0008rule_position_handle_0
Executable file
162
tests/shell/testcases/json/0008rule_position_handle_0
Executable file
@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NFT_TEST_REQUIRES(NFT_TEST_HAVE_json)
|
||||
|
||||
# Test JSON handle-based rule positioning
|
||||
# Verifies explicit format uses handle for positioning while implicit format ignores it
|
||||
|
||||
set -e
|
||||
|
||||
$NFT flush ruleset
|
||||
|
||||
echo "Test 1: ADD with handle positions AFTER"
|
||||
$NFT -f - <<EOF
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
tcp dport 80 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Get handle of first rule (tcp dport 22)
|
||||
HANDLE=$($NFT -a list chain inet test c | sed -n 's/.*tcp dport 22 .* handle \([0-9]\+\)/\1/p')
|
||||
|
||||
# Add after handle (should be between 22 and 80)
|
||||
$NFT -j -f - <<EOF
|
||||
{"nftables": [{"add": {"rule": {"family": "inet", "table": "test", "chain": "c", "handle": $HANDLE, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 443}}, {"accept": null}]}}}]}
|
||||
EOF
|
||||
|
||||
# Verify order: 22, 443, 80
|
||||
RULES=$($NFT list chain inet test c | grep -o "tcp dport [0-9]*")
|
||||
EXPECTED="tcp dport 22
|
||||
tcp dport 443
|
||||
tcp dport 80"
|
||||
|
||||
if [ "$RULES" = "$EXPECTED" ]; then
|
||||
echo "PASS: Rule added after handle"
|
||||
else
|
||||
echo "FAIL: Expected order 22,443,80, got:"
|
||||
echo "$RULES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Test 2: INSERT with handle positions BEFORE"
|
||||
$NFT flush ruleset
|
||||
$NFT -f - <<EOF
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
tcp dport 80 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Get handle of second rule (tcp dport 80)
|
||||
HANDLE=$($NFT -a list chain inet test c | sed -n 's/.*tcp dport 80 .* handle \([0-9]\+\)/\1/p')
|
||||
|
||||
# Insert before handle
|
||||
$NFT -j -f - <<EOF
|
||||
{"nftables": [{"insert": {"rule": {"family": "inet", "table": "test", "chain": "c", "handle": $HANDLE, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 443}}, {"accept": null}]}}}]}
|
||||
EOF
|
||||
|
||||
# Verify order: 22, 443, 80
|
||||
RULES=$($NFT list chain inet test c | grep -o "tcp dport [0-9]*")
|
||||
if [ "$RULES" = "$EXPECTED" ]; then
|
||||
echo "PASS: Rule inserted before handle"
|
||||
else
|
||||
echo "FAIL: Expected order 22,443,80, got:"
|
||||
echo "$RULES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Test 3: INSERT without handle positions at beginning"
|
||||
$NFT flush ruleset
|
||||
$NFT -f - <<EOF
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
tcp dport 80 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Insert without handle (should go to beginning)
|
||||
$NFT -j -f - <<EOF
|
||||
{"nftables": [{"insert": {"rule": {"family": "inet", "table": "test", "chain": "c", "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 443}}, {"accept": null}]}}}]}
|
||||
EOF
|
||||
|
||||
# Verify order: 443, 22, 80
|
||||
RULES=$($NFT list chain inet test c | grep -o "tcp dport [0-9]*")
|
||||
EXPECTED_INSERT="tcp dport 443
|
||||
tcp dport 22
|
||||
tcp dport 80"
|
||||
|
||||
if [ "$RULES" = "$EXPECTED_INSERT" ]; then
|
||||
echo "PASS: Rule inserted at beginning without handle"
|
||||
else
|
||||
echo "FAIL: Expected order 443,22,80, got:"
|
||||
echo "$RULES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Test 4: Multiple commands in single transaction"
|
||||
$NFT flush ruleset
|
||||
$NFT -f - <<EOF
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Get handle
|
||||
HANDLE=$($NFT -a list chain inet test c | sed -n 's/.*tcp dport 22 .* handle \([0-9]\+\)/\1/p')
|
||||
|
||||
# Add two rules after same handle in single transaction
|
||||
$NFT -j -f - <<EOF
|
||||
{"nftables": [
|
||||
{"add": {"rule": {"family": "inet", "table": "test", "chain": "c", "handle": $HANDLE, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 80}}, {"accept": null}]}}},
|
||||
{"add": {"rule": {"family": "inet", "table": "test", "chain": "c", "handle": $HANDLE, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 443}}, {"accept": null}]}}}
|
||||
]}
|
||||
EOF
|
||||
|
||||
# Verify: Both should be after handle 22
|
||||
# In a transaction, both position to same handle, so added in reverse order
|
||||
# Order should be: 22, then 443, then 80 (last add goes immediately after position)
|
||||
RULES=$($NFT list chain inet test c | grep -o "tcp dport [0-9]*")
|
||||
EXPECTED_MULTI="tcp dport 22
|
||||
tcp dport 443
|
||||
tcp dport 80"
|
||||
|
||||
if [ "$RULES" = "$EXPECTED_MULTI" ]; then
|
||||
echo "PASS: Multiple rules in transaction positioned correctly"
|
||||
else
|
||||
echo "FAIL: Expected order 22,443,80, got:"
|
||||
echo "$RULES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Test 5: Implicit format ignores handle"
|
||||
$NFT flush ruleset
|
||||
$NFT -f - <<EOF
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Implicit format with non-existent handle should succeed (handle ignored)
|
||||
$NFT -j -f - <<EOF
|
||||
{"nftables": [{"rule": {"family": "inet", "table": "test", "chain": "c", "handle": 9999, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 80}}, {"accept": null}]}}]}
|
||||
EOF
|
||||
|
||||
if $NFT list chain inet test c | grep -q "tcp dport 80"; then
|
||||
echo "PASS: Implicit format ignores handle"
|
||||
else
|
||||
echo "FAIL: Implicit format should have added rule despite non-existent handle"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All positioning tests passed!"
|
||||
@ -0,0 +1,76 @@
|
||||
{
|
||||
"nftables": [
|
||||
{
|
||||
"metainfo": {
|
||||
"version": "VERSION",
|
||||
"release_name": "RELEASE_NAME",
|
||||
"json_schema_version": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"family": "inet",
|
||||
"name": "test",
|
||||
"handle": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"chain": {
|
||||
"family": "inet",
|
||||
"table": "test",
|
||||
"name": "c",
|
||||
"handle": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"rule": {
|
||||
"family": "inet",
|
||||
"table": "test",
|
||||
"chain": "c",
|
||||
"handle": 0,
|
||||
"expr": [
|
||||
{
|
||||
"match": {
|
||||
"op": "==",
|
||||
"left": {
|
||||
"payload": {
|
||||
"protocol": "tcp",
|
||||
"field": "dport"
|
||||
}
|
||||
},
|
||||
"right": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"accept": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"rule": {
|
||||
"family": "inet",
|
||||
"table": "test",
|
||||
"chain": "c",
|
||||
"handle": 0,
|
||||
"expr": [
|
||||
{
|
||||
"match": {
|
||||
"op": "==",
|
||||
"left": {
|
||||
"payload": {
|
||||
"protocol": "tcp",
|
||||
"field": "dport"
|
||||
}
|
||||
},
|
||||
"right": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"accept": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
table inet test {
|
||||
chain c {
|
||||
tcp dport 22 accept
|
||||
tcp dport 80 accept
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user