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

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: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
6978cdb1 63ce3940

+94 -36
+94 -36
tools/testing/selftests/netfilter/nft_nat.sh
··· 6 6 # Kselftest framework requirement - SKIP code is 4. 7 7 ksft_skip=4 8 8 ret=0 9 + test_inet_nat=true 9 10 10 11 nft --version > /dev/null 2>&1 11 12 if [ $? -ne 0 ];then ··· 142 141 143 142 test_local_dnat6() 144 143 { 144 + local family=$1 145 145 local lret=0 146 + local IPF="" 147 + 148 + if [ $family = "inet" ];then 149 + IPF="ip6" 150 + fi 151 + 146 152 ip netns exec ns0 nft -f - <<EOF 147 - table ip6 nat { 153 + table $family nat { 148 154 chain output { 149 155 type nat hook output priority 0; policy accept; 150 - ip6 daddr dead:1::99 dnat to dead:2::99 156 + ip6 daddr dead:1::99 dnat $IPF to dead:2::99 151 157 } 152 158 } 153 159 EOF 154 160 if [ $? -ne 0 ]; then 155 - echo "SKIP: Could not add add ip6 dnat hook" 161 + echo "SKIP: Could not add add $family dnat hook" 156 162 return $ksft_skip 157 163 fi 158 164 ··· 209 201 fi 210 202 done 211 203 212 - test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was NATted to ns2" 204 + test $lret -eq 0 && echo "PASS: ipv6 ping to ns1 was $family NATted to ns2" 213 205 ip netns exec ns0 nft flush chain ip6 nat output 214 206 215 207 return $lret ··· 217 209 218 210 test_local_dnat() 219 211 { 212 + local family=$1 220 213 local lret=0 221 - ip netns exec ns0 nft -f - <<EOF 222 - table ip nat { 214 + local IPF="" 215 + 216 + if [ $family = "inet" ];then 217 + IPF="ip" 218 + fi 219 + 220 + ip netns exec ns0 nft -f - <<EOF 2>/dev/null 221 + table $family nat { 223 222 chain output { 224 223 type nat hook output priority 0; policy accept; 225 - ip daddr 10.0.1.99 dnat to 10.0.2.99 224 + ip daddr 10.0.1.99 dnat $IPF to 10.0.2.99 226 225 } 227 226 } 228 227 EOF 228 + if [ $? -ne 0 ]; then 229 + if [ $family = "inet" ];then 230 + echo "SKIP: inet nat tests" 231 + test_inet_nat=false 232 + return $ksft_skip 233 + fi 234 + echo "SKIP: Could not add add $family dnat hook" 235 + return $ksft_skip 236 + fi 237 + 229 238 # ping netns1, expect rewrite to netns2 230 239 ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null 231 240 if [ $? -ne 0 ]; then ··· 289 264 fi 290 265 done 291 266 292 - test $lret -eq 0 && echo "PASS: ping to ns1 was NATted to ns2" 267 + test $lret -eq 0 && echo "PASS: ping to ns1 was $family NATted to ns2" 293 268 294 - ip netns exec ns0 nft flush chain ip nat output 269 + ip netns exec ns0 nft flush chain $family nat output 295 270 296 271 reset_counters 297 272 ip netns exec ns0 ping -q -c 1 10.0.1.99 > /dev/null ··· 338 313 fi 339 314 done 340 315 341 - test $lret -eq 0 && echo "PASS: ping to ns1 OK after nat output chain flush" 316 + test $lret -eq 0 && echo "PASS: ping to ns1 OK after $family nat output chain flush" 342 317 343 318 return $lret 344 319 } ··· 346 321 347 322 test_masquerade6() 348 323 { 324 + local family=$1 349 325 local lret=0 350 326 351 327 ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ··· 377 351 378 352 # add masquerading rule 379 353 ip netns exec ns0 nft -f - <<EOF 380 - table ip6 nat { 354 + table $family nat { 381 355 chain postrouting { 382 356 type nat hook postrouting priority 0; policy accept; 383 357 meta oif veth0 masquerade 384 358 } 385 359 } 386 360 EOF 361 + if [ $? -ne 0 ]; then 362 + echo "SKIP: Could not add add $family masquerade hook" 363 + return $ksft_skip 364 + fi 365 + 387 366 ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 388 367 if [ $? -ne 0 ] ; then 389 - echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading" 368 + echo "ERROR: cannot ping ns1 from ns2 with active $family masquerading" 390 369 lret=1 391 370 fi 392 371 ··· 428 397 fi 429 398 done 430 399 431 - ip netns exec ns0 nft flush chain ip6 nat postrouting 400 + ip netns exec ns0 nft flush chain $family nat postrouting 432 401 if [ $? -ne 0 ]; then 433 - echo "ERROR: Could not flush ip6 nat postrouting" 1>&2 402 + echo "ERROR: Could not flush $family nat postrouting" 1>&2 434 403 lret=1 435 404 fi 436 405 437 - test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2" 406 + test $lret -eq 0 && echo "PASS: $family IPv6 masquerade for ns2" 438 407 439 408 return $lret 440 409 } 441 410 442 411 test_masquerade() 443 412 { 413 + local family=$1 444 414 local lret=0 445 415 446 416 ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ··· 472 440 473 441 # add masquerading rule 474 442 ip netns exec ns0 nft -f - <<EOF 475 - table ip nat { 443 + table $family nat { 476 444 chain postrouting { 477 445 type nat hook postrouting priority 0; policy accept; 478 446 meta oif veth0 masquerade 479 447 } 480 448 } 481 449 EOF 450 + if [ $? -ne 0 ]; then 451 + echo "SKIP: Could not add add $family masquerade hook" 452 + return $ksft_skip 453 + fi 454 + 482 455 ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 483 456 if [ $? -ne 0 ] ; then 484 - echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading" 457 + echo "ERROR: cannot ping ns1 from ns2 with active $family masquerading" 485 458 lret=1 486 459 fi 487 460 ··· 522 485 fi 523 486 done 524 487 525 - ip netns exec ns0 nft flush chain ip nat postrouting 488 + ip netns exec ns0 nft flush chain $family nat postrouting 526 489 if [ $? -ne 0 ]; then 527 - echo "ERROR: Could not flush nat postrouting" 1>&2 490 + echo "ERROR: Could not flush $family nat postrouting" 1>&2 528 491 lret=1 529 492 fi 530 493 531 - test $lret -eq 0 && echo "PASS: IP masquerade for ns2" 494 + test $lret -eq 0 && echo "PASS: $family IP masquerade for ns2" 532 495 533 496 return $lret 534 497 } 535 498 536 499 test_redirect6() 537 500 { 501 + local family=$1 538 502 local lret=0 539 503 540 504 ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null ··· 565 527 566 528 # add redirect rule 567 529 ip netns exec ns0 nft -f - <<EOF 568 - table ip6 nat { 530 + table $family nat { 569 531 chain prerouting { 570 532 type nat hook prerouting priority 0; policy accept; 571 533 meta iif veth1 meta l4proto icmpv6 ip6 saddr dead:2::99 ip6 daddr dead:1::99 redirect 572 534 } 573 535 } 574 536 EOF 537 + if [ $? -ne 0 ]; then 538 + echo "SKIP: Could not add add $family redirect hook" 539 + return $ksft_skip 540 + fi 541 + 575 542 ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 576 543 if [ $? -ne 0 ] ; then 577 - echo "ERROR: cannot ping ns1 from ns2 with active ip6 redirect" 544 + echo "ERROR: cannot ping ns1 from ns2 via ipv6 with active $family redirect" 578 545 lret=1 579 546 fi 580 547 ··· 603 560 fi 604 561 done 605 562 606 - ip netns exec ns0 nft delete table ip6 nat 563 + ip netns exec ns0 nft delete table $family nat 607 564 if [ $? -ne 0 ]; then 608 - echo "ERROR: Could not delete ip6 nat table" 1>&2 565 + echo "ERROR: Could not delete $family nat table" 1>&2 609 566 lret=1 610 567 fi 611 568 612 - test $lret -eq 0 && echo "PASS: IPv6 redirection for ns2" 569 + test $lret -eq 0 && echo "PASS: $family IPv6 redirection for ns2" 613 570 614 571 return $lret 615 572 } 616 573 617 574 test_redirect() 618 575 { 576 + local family=$1 619 577 local lret=0 620 578 621 579 ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null ··· 647 603 648 604 # add redirect rule 649 605 ip netns exec ns0 nft -f - <<EOF 650 - table ip nat { 606 + table $family nat { 651 607 chain prerouting { 652 608 type nat hook prerouting priority 0; policy accept; 653 609 meta iif veth1 ip protocol icmp ip saddr 10.0.2.99 ip daddr 10.0.1.99 redirect 654 610 } 655 611 } 656 612 EOF 613 + if [ $? -ne 0 ]; then 614 + echo "SKIP: Could not add add $family redirect hook" 615 + return $ksft_skip 616 + fi 617 + 657 618 ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 658 619 if [ $? -ne 0 ] ; then 659 - echo "ERROR: cannot ping ns1 from ns2 with active ip redirect" 620 + echo "ERROR: cannot ping ns1 from ns2 with active $family ip redirect" 660 621 lret=1 661 622 fi 662 623 ··· 686 637 fi 687 638 done 688 639 689 - ip netns exec ns0 nft delete table ip nat 640 + ip netns exec ns0 nft delete table $family nat 690 641 if [ $? -ne 0 ]; then 691 - echo "ERROR: Could not delete nat table" 1>&2 642 + echo "ERROR: Could not delete $family nat table" 1>&2 692 643 lret=1 693 644 fi 694 645 695 - test $lret -eq 0 && echo "PASS: IP redirection for ns2" 646 + test $lret -eq 0 && echo "PASS: $family IP redirection for ns2" 696 647 697 648 return $lret 698 649 } ··· 795 746 fi 796 747 797 748 reset_counters 798 - test_local_dnat 799 - test_local_dnat6 749 + test_local_dnat ip 750 + test_local_dnat6 ip6 751 + reset_counters 752 + $test_inet_nat && test_local_dnat inet 753 + $test_inet_nat && test_local_dnat6 inet 800 754 801 755 reset_counters 802 - test_masquerade 803 - test_masquerade6 756 + test_masquerade ip 757 + test_masquerade6 ip6 758 + reset_counters 759 + $test_inet_nat && test_masquerade inet 760 + $test_inet_nat && test_masquerade6 inet 804 761 805 762 reset_counters 806 - test_redirect 807 - test_redirect6 763 + test_redirect ip 764 + test_redirect6 ip6 765 + reset_counters 766 + $test_inet_nat && test_redirect inet 767 + $test_inet_nat && test_redirect6 inet 808 768 809 769 for i in 0 1 2; do ip netns del ns$i;done 810 770