Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nat: really support inet nat without l3 address

When no l3 address is given, priv->family is set to NFPROTO_INET and
the evaluation function isn't called.

Call it too so l4-only rewrite can work.
Also add a test case for this.

Fixes: a33f387ecd5aa ("netfilter: nft_nat: allow to specify layer 4 protocol NAT only")
Reported-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
282e5f8f 0a375c82

+45 -1
+2 -1
net/netfilter/nft_nat.c
··· 335 335 { 336 336 const struct nft_nat *priv = nft_expr_priv(expr); 337 337 338 - if (priv->family == nft_pf(pkt)) 338 + if (priv->family == nft_pf(pkt) || 339 + priv->family == NFPROTO_INET) 339 340 nft_nat_eval(expr, regs, pkt); 340 341 } 341 342
+43
tools/testing/selftests/netfilter/nft_nat.sh
··· 374 374 return $lret 375 375 } 376 376 377 + test_local_dnat_portonly() 378 + { 379 + local family=$1 380 + local daddr=$2 381 + local lret=0 382 + local sr_s 383 + local sr_r 384 + 385 + ip netns exec "$ns0" nft -f /dev/stdin <<EOF 386 + table $family nat { 387 + chain output { 388 + type nat hook output priority 0; policy accept; 389 + meta l4proto tcp dnat to :2000 390 + 391 + } 392 + } 393 + EOF 394 + if [ $? -ne 0 ]; then 395 + if [ $family = "inet" ];then 396 + echo "SKIP: inet port test" 397 + test_inet_nat=false 398 + return 399 + fi 400 + echo "SKIP: Could not add $family dnat hook" 401 + return 402 + fi 403 + 404 + echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 & 405 + sc_s=$! 406 + 407 + result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT) 408 + 409 + if [ "$result" = "SERVER-inet" ];then 410 + echo "PASS: inet port rewrite without l3 address" 411 + else 412 + echo "ERROR: inet port rewrite" 413 + ret=1 414 + fi 415 + } 377 416 378 417 test_masquerade6() 379 418 { ··· 1187 1148 reset_counters 1188 1149 test_local_dnat ip 1189 1150 test_local_dnat6 ip6 1151 + 1152 + reset_counters 1153 + test_local_dnat_portonly inet 10.0.1.99 1154 + 1190 1155 reset_counters 1191 1156 $test_inet_nat && test_local_dnat inet 1192 1157 $test_inet_nat && test_local_dnat6 inet