Commit 6978cdb1 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

kselftests: extend nft_nat with inet family based nat hooks

With older nft versions, this will cause:
[..]
PASS: ipv6 ping to ns1 was ip6 NATted to ns2
/dev/stdin:4:30-31: Error: syntax error, unexpected to, expecting newline or semicolon
                ip daddr 10.0.1.99 dnat ip to 10.0.2.99
                                           ^^
SKIP: inet nat tests
PASS: ip IP masquerade for ns2
[..]

as there is currently no way to detect if nft will be able to parse
the inet format.

redirect and masquerade tests need to be skipped in this case for inet
too because nft userspace has overzealous family check and rejects their
use in the inet family.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 63ce3940
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
# Kselftest framework requirement - SKIP code is 4. # Kselftest framework requirement - SKIP code is 4.
ksft_skip=4 ksft_skip=4
ret=0 ret=0
test_inet_nat=true
nft --version > /dev/null 2>&1 nft --version > /dev/null 2>&1
if [ $? -ne 0 ];then if [ $? -ne 0 ];then
...@@ -141,17 +142,24 @@ reset_counters() ...@@ -141,17 +142,24 @@ reset_counters()
test_local_dnat6() test_local_dnat6()
{ {
local family=$1
local lret=0 local lret=0
local IPF=""
if [ $family = "inet" ];then
IPF="ip6"
fi
ip netns exec ns0 nft -f - <<EOF ip netns exec ns0 nft -f - <<EOF
table ip6 nat { table $family nat {
chain output { chain output {
type nat hook output priority 0; policy accept; type nat hook output priority 0; policy accept;
ip6 daddr dead:1::99 dnat to dead:2::99 ip6 daddr dead:1::99 dnat $IPF to dead:2::99
} }
} }
EOF EOF
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "SKIP: Could not add add ip6 dnat hook" echo "SKIP: Could not add add $family dnat hook"
return $ksft_skip return $ksft_skip
fi fi
...@@ -201,7 +209,7 @@ EOF ...@@ -201,7 +209,7 @@ EOF
fi fi
done done
test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was NATted to ns2" test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was $family NATted to ns2"
ip netns exec ns0 nft flush chain ip6 nat output ip netns exec ns0 nft flush chain ip6 nat output
return $lret return $lret
...@@ -209,15 +217,32 @@ EOF ...@@ -209,15 +217,32 @@ EOF
test_local_dnat() test_local_dnat()
{ {
local family=$1
local lret=0 local lret=0
ip netns exec ns0 nft -f - <<EOF local IPF=""
table ip nat {
if [ $family = "inet" ];then
IPF="ip"
fi
ip netns exec ns0 nft -f - <<EOF 2>/dev/null
table $family nat {
chain output { chain output {
type nat hook output priority 0; policy accept; type nat hook output priority 0; policy accept;
ip daddr 10.0.1.99 dnat to 10.0.2.99 ip daddr 10.0.1.99 dnat $IPF to 10.0.2.99
} }
} }
EOF EOF
if [ $? -ne 0 ]; then
if [ $family = "inet" ];then
echo "SKIP: inet nat tests"
test_inet_nat=false
return $ksft_skip
fi
echo "SKIP: Could not add add $family dnat hook"
return $ksft_skip
fi
# ping netns1, expect rewrite to netns2 # ping netns1, expect rewrite to netns2
ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
...@@ -264,9 +289,9 @@ EOF ...@@ -264,9 +289,9 @@ EOF
fi fi
done done
test $lret -eq 0 && echo "PASS: ping to ns1 was NATted to ns2" test $lret -eq 0 && echo "PASS: ping to ns1 was $family NATted to ns2"
ip netns exec ns0 nft flush chain ip nat output ip netns exec ns0 nft flush chain $family nat output
reset_counters reset_counters
ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null
...@@ -313,7 +338,7 @@ EOF ...@@ -313,7 +338,7 @@ EOF
fi fi
done done
test $lret -eq 0 && echo "PASS: ping to ns1 OK after nat output chain flush" test $lret -eq 0 && echo "PASS: ping to ns1 OK after $family nat output chain flush"
return $lret return $lret
} }
...@@ -321,6 +346,7 @@ EOF ...@@ -321,6 +346,7 @@ EOF
test_masquerade6() test_masquerade6()
{ {
local family=$1
local lret=0 local lret=0
ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
...@@ -351,16 +377,21 @@ test_masquerade6() ...@@ -351,16 +377,21 @@ test_masquerade6()
# add masquerading rule # add masquerading rule
ip netns exec ns0 nft -f - <<EOF ip netns exec ns0 nft -f - <<EOF
table ip6 nat { table $family nat {
chain postrouting { chain postrouting {
type nat hook postrouting priority 0; policy accept; type nat hook postrouting priority 0; policy accept;
meta oif veth0 masquerade meta oif veth0 masquerade
} }
} }
EOF EOF
if [ $? -ne 0 ]; then
echo "SKIP: Could not add add $family masquerade hook"
return $ksft_skip
fi
ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading" echo "ERROR: cannot ping ns1 from ns2 with active $family masquerading"
lret=1 lret=1
fi fi
...@@ -397,19 +428,20 @@ EOF ...@@ -397,19 +428,20 @@ EOF
fi fi
done done
ip netns exec ns0 nft flush chain ip6 nat postrouting ip netns exec ns0 nft flush chain $family nat postrouting
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR: Could not flush ip6 nat postrouting" 1>&2 echo "ERROR: Could not flush $family nat postrouting" 1>&2
lret=1 lret=1
fi fi
test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2" test $lret -eq 0 && echo "PASS: $family IPv6 masquerade for ns2"
return $lret return $lret
} }
test_masquerade() test_masquerade()
{ {
local family=$1
local lret=0 local lret=0
ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
...@@ -440,16 +472,21 @@ test_masquerade() ...@@ -440,16 +472,21 @@ test_masquerade()
# add masquerading rule # add masquerading rule
ip netns exec ns0 nft -f - <<EOF ip netns exec ns0 nft -f - <<EOF
table ip nat { table $family nat {
chain postrouting { chain postrouting {
type nat hook postrouting priority 0; policy accept; type nat hook postrouting priority 0; policy accept;
meta oif veth0 masquerade meta oif veth0 masquerade
} }
} }
EOF EOF
if [ $? -ne 0 ]; then
echo "SKIP: Could not add add $family masquerade hook"
return $ksft_skip
fi
ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading" echo "ERROR: cannot ping ns1 from ns2 with active $family masquerading"
lret=1 lret=1
fi fi
...@@ -485,19 +522,20 @@ EOF ...@@ -485,19 +522,20 @@ EOF
fi fi
done done
ip netns exec ns0 nft flush chain ip nat postrouting ip netns exec ns0 nft flush chain $family nat postrouting
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR: Could not flush nat postrouting" 1>&2 echo "ERROR: Could not flush $family nat postrouting" 1>&2
lret=1 lret=1
fi fi
test $lret -eq 0 && echo "PASS: IP masquerade for ns2" test $lret -eq 0 && echo "PASS: $family IP masquerade for ns2"
return $lret return $lret
} }
test_redirect6() test_redirect6()
{ {
local family=$1
local lret=0 local lret=0
ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
...@@ -527,16 +565,21 @@ test_redirect6() ...@@ -527,16 +565,21 @@ test_redirect6()
# add redirect rule # add redirect rule
ip netns exec ns0 nft -f - <<EOF ip netns exec ns0 nft -f - <<EOF
table ip6 nat { table $family nat {
chain prerouting { chain prerouting {
type nat hook prerouting priority 0; policy accept; type nat hook prerouting priority 0; policy accept;
meta iif veth1 meta l4proto icmpv6 ip6 saddr dead:2::99 ip6 daddr dead:1::99 redirect meta iif veth1 meta l4proto icmpv6 ip6 saddr dead:2::99 ip6 daddr dead:1::99 redirect
} }
} }
EOF EOF
if [ $? -ne 0 ]; then
echo "SKIP: Could not add add $family redirect hook"
return $ksft_skip
fi
ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
echo "ERROR: cannot ping ns1 from ns2 with active ip6 redirect" echo "ERROR: cannot ping ns1 from ns2 via ipv6 with active $family redirect"
lret=1 lret=1
fi fi
...@@ -560,19 +603,20 @@ EOF ...@@ -560,19 +603,20 @@ EOF
fi fi
done done
ip netns exec ns0 nft delete table ip6 nat ip netns exec ns0 nft delete table $family nat
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR: Could not delete ip6 nat table" 1>&2 echo "ERROR: Could not delete $family nat table" 1>&2
lret=1 lret=1
fi fi
test $lret -eq 0 && echo "PASS: IPv6 redirection for ns2" test $lret -eq 0 && echo "PASS: $family IPv6 redirection for ns2"
return $lret return $lret
} }
test_redirect() test_redirect()
{ {
local family=$1
local lret=0 local lret=0
ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
...@@ -603,16 +647,21 @@ test_redirect() ...@@ -603,16 +647,21 @@ test_redirect()
# add redirect rule # add redirect rule
ip netns exec ns0 nft -f - <<EOF ip netns exec ns0 nft -f - <<EOF
table ip nat { table $family nat {
chain prerouting { chain prerouting {
type nat hook prerouting priority 0; policy accept; type nat hook prerouting priority 0; policy accept;
meta iif veth1 ip protocol icmp ip saddr 10.0.2.99 ip daddr 10.0.1.99 redirect meta iif veth1 ip protocol icmp ip saddr 10.0.2.99 ip daddr 10.0.1.99 redirect
} }
} }
EOF EOF
if [ $? -ne 0 ]; then
echo "SKIP: Could not add add $family redirect hook"
return $ksft_skip
fi
ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
echo "ERROR: cannot ping ns1 from ns2 with active ip redirect" echo "ERROR: cannot ping ns1 from ns2 with active $family ip redirect"
lret=1 lret=1
fi fi
...@@ -637,13 +686,13 @@ EOF ...@@ -637,13 +686,13 @@ EOF
fi fi
done done
ip netns exec ns0 nft delete table ip nat ip netns exec ns0 nft delete table $family nat
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR: Could not delete nat table" 1>&2 echo "ERROR: Could not delete $family nat table" 1>&2
lret=1 lret=1
fi fi
test $lret -eq 0 && echo "PASS: IP redirection for ns2" test $lret -eq 0 && echo "PASS: $family IP redirection for ns2"
return $lret return $lret
} }
...@@ -746,16 +795,25 @@ if [ $ret -eq 0 ];then ...@@ -746,16 +795,25 @@ if [ $ret -eq 0 ];then
fi fi
reset_counters reset_counters
test_local_dnat test_local_dnat ip
test_local_dnat6 test_local_dnat6 ip6
reset_counters
$test_inet_nat && test_local_dnat inet
$test_inet_nat && test_local_dnat6 inet
reset_counters reset_counters
test_masquerade test_masquerade ip
test_masquerade6 test_masquerade6 ip6
reset_counters
$test_inet_nat && test_masquerade inet
$test_inet_nat && test_masquerade6 inet
reset_counters reset_counters
test_redirect test_redirect ip
test_redirect6 test_redirect6 ip6
reset_counters
$test_inet_nat && test_redirect inet
$test_inet_nat && test_redirect6 inet
for i in 0 1 2; do ip netns del ns$i;done for i in 0 1 2; do ip netns del ns$i;done
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment