1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2024 Rubicon Communications, LLC (Netgate) 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26 27. $(atf_get_srcdir)/utils.subr 28 29nat64_setup_base() 30{ 31 pft_init 32 33 epair_link=$(vnet_mkepair) 34 epair=$(vnet_mkepair) 35 36 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 37 route -6 add default 2001:db8::1 38 39 vnet_mkjail rtr ${epair}b ${epair_link}a 40 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 41 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 42 43 vnet_mkjail dst ${epair_link}b 44 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 45 jexec dst route add default 192.0.2.1 46 47 # Sanity checks 48 atf_check -s exit:0 -o ignore \ 49 ping6 -c 1 2001:db8::1 50 atf_check -s exit:0 -o ignore \ 51 jexec dst ping -c 1 192.0.2.1 52 53 jexec rtr pfctl -e 54} 55 56nat64_setup_in() 57{ 58 nat64_setup_base 59 pft_set_rules rtr \ 60 "set reassemble yes" \ 61 "set state-policy if-bound" \ 62 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" 63} 64 65nat64_setup_out() 66{ 67 nat64_setup_base 68 jexec rtr sysctl net.inet6.ip6.forwarding=1 69 # AF translation happens post-routing, traffic must be directed 70 # towards the outbound interface using routes for the original AF. 71 # jexec rtr ifconfig ${epair_link}a inet6 2001:db8:2::1/64 up no_dad 72 jexec rtr route add -inet6 64:ff9b::/96 -iface ${epair_link}a; 73 pft_set_rules rtr \ 74 "set reassemble yes" \ 75 "set state-policy if-bound" \ 76 "pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ 77 "pass in quick on ${epair}b from any to 64:ff9b::/96" \ 78 "pass out quick on ${epair_link}a from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" \ 79 "block" 80} 81 82atf_test_case "icmp_echo_in" "cleanup" 83icmp_echo_in_head() 84{ 85 atf_set descr 'Basic NAT64 ICMP echo test on inbound interface' 86 atf_set require.user root 87} 88 89icmp_echo_in_body() 90{ 91 nat64_setup_in 92 93 # One ping 94 atf_check -s exit:0 -o ignore \ 95 ping6 -c 1 64:ff9b::192.0.2.2 96 97 # Make sure packets make it even when state is established 98 atf_check -s exit:0 \ 99 -o match:'5 packets transmitted, 5 packets received, 0.0% packet loss' \ 100 ping6 -c 5 64:ff9b::192.0.2.2 101} 102 103icmp_echo_in_cleanup() 104{ 105 pft_cleanup 106} 107 108atf_test_case "icmp_echo_out" "cleanup" 109icmp_echo_out_head() 110{ 111 atf_set descr 'Basic NAT64 ICMP echo test on outbound interface' 112 atf_set require.user root 113} 114 115icmp_echo_out_body() 116{ 117 nat64_setup_out 118 119 # One ping 120 atf_check -s exit:0 -o ignore \ 121 ping6 -c 1 64:ff9b::192.0.2.2 122 123 # Make sure packets make it even when state is established 124 atf_check -s exit:0 \ 125 -o match:'5 packets transmitted, 5 packets received, 0.0% packet loss' \ 126 ping6 -c 5 64:ff9b::192.0.2.2 127} 128 129icmp_echo_out_cleanup() 130{ 131 pft_cleanup 132} 133 134atf_test_case "fragmentation_in" "cleanup" 135fragmentation_in_head() 136{ 137 atf_set descr 'Test fragmented packets on inbound interface' 138 atf_set require.user root 139} 140 141fragmentation_in_body() 142{ 143 nat64_setup_in 144 145 atf_check -s exit:0 -o ignore \ 146 ping6 -c 1 -s 1280 64:ff9b::192.0.2.2 147 148 atf_check -s exit:0 \ 149 -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \ 150 ping6 -c 3 -s 2000 64:ff9b::192.0.2.2 151 atf_check -s exit:0 \ 152 -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \ 153 ping6 -c 3 -s 10000 -b 20000 64:ff9b::192.0.2.2 154} 155 156fragmentation_in_cleanup() 157{ 158 pft_cleanup 159} 160 161atf_test_case "fragmentation_out" "cleanup" 162fragmentation_out_head() 163{ 164 atf_set descr 'Test fragmented packets on outbound interface' 165 atf_set require.user root 166} 167 168fragmentation_out_body() 169{ 170 nat64_setup_out 171 172 atf_check -s exit:0 -o ignore \ 173 ping6 -c 1 -s 1280 64:ff9b::192.0.2.2 174 175 atf_check -s exit:0 \ 176 -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \ 177 ping6 -c 3 -s 2000 64:ff9b::192.0.2.2 178 atf_check -s exit:0 \ 179 -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \ 180 ping6 -c 3 -s 10000 -b 20000 64:ff9b::192.0.2.2 181} 182 183fragmentation_out_cleanup() 184{ 185 pft_cleanup 186} 187 188atf_test_case "tcp_in" "cleanup" 189tcp_in_head() 190{ 191 atf_set descr 'TCP NAT64 test on inbound interface' 192 atf_set require.user root 193} 194 195tcp_in_body() 196{ 197 nat64_setup_in 198 199 echo "foo" | jexec dst nc -l 1234 & 200 201 # Sanity check & delay for nc startup 202 atf_check -s exit:0 -o ignore \ 203 ping6 -c 1 64:ff9b::192.0.2.2 204 205 rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) 206 if [ "${rcv}" != "foo" ]; 207 then 208 echo "rcv=${rcv}" 209 atf_fail "Failed to connect to TCP server" 210 fi 211} 212 213tcp_in_cleanup() 214{ 215 pft_cleanup 216} 217 218atf_test_case "tcp_out" "cleanup" 219tcp_out_head() 220{ 221 atf_set descr 'TCP NAT64 test on outbound interface' 222 atf_set require.user root 223} 224 225tcp_out_body() 226{ 227 nat64_setup_out 228 229 echo "foo" | jexec dst nc -l 1234 & 230 231 # Sanity check & delay for nc startup 232 atf_check -s exit:0 -o ignore \ 233 ping6 -c 1 64:ff9b::192.0.2.2 234 235 rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) 236 if [ "${rcv}" != "foo" ]; 237 then 238 echo "rcv=${rcv}" 239 atf_fail "Failed to connect to TCP server" 240 fi 241} 242 243tcp_out_cleanup() 244{ 245 pft_cleanup 246} 247 248atf_test_case "udp_in" "cleanup" 249udp_in_head() 250{ 251 atf_set descr 'UDP NAT64 test on inbound interface' 252 atf_set require.user root 253} 254 255udp_in_body() 256{ 257 nat64_setup_in 258 259 echo "foo" | jexec dst nc -u -l 1234 & 260 261 # Sanity check & delay for nc startup 262 atf_check -s exit:0 -o ignore \ 263 ping6 -c 1 64:ff9b::192.0.2.2 264 265 rcv=$(echo bar | nc -w 3 -6 -u 64:ff9b::c000:202 1234) 266 if [ "${rcv}" != "foo" ]; 267 then 268 echo "rcv=${rcv}" 269 atf_fail "Failed to connect to UDP server" 270 fi 271} 272 273udp_in_cleanup() 274{ 275 pft_cleanup 276} 277 278atf_test_case "udp_out" "cleanup" 279udp_out_head() 280{ 281 atf_set descr 'UDP NAT64 test on outbound interface' 282 atf_set require.user root 283} 284 285udp_out_body() 286{ 287 nat64_setup_out 288 289 echo "foo" | jexec dst nc -u -l 1234 & 290 291 # Sanity check & delay for nc startup 292 atf_check -s exit:0 -o ignore \ 293 ping6 -c 1 64:ff9b::192.0.2.2 294 295 rcv=$(echo bar | nc -w 3 -6 -u 64:ff9b::c000:202 1234) 296 if [ "${rcv}" != "foo" ]; 297 then 298 echo "rcv=${rcv}" 299 atf_fail "Failed to connect to UDP server" 300 fi 301} 302 303udp_out_cleanup() 304{ 305 pft_cleanup 306} 307 308atf_test_case "sctp_in" "cleanup" 309sctp_in_head() 310{ 311 atf_set descr 'SCTP NAT64 test on inbound interface' 312 atf_set require.user root 313} 314 315sctp_in_body() 316{ 317 nat64_setup_in 318 if ! kldstat -q -m sctp; then 319 atf_skip "This test requires SCTP" 320 fi 321 322 echo "foo" | jexec dst nc --sctp -N -l 1234 & 323 324 # Sanity check & delay for nc startup 325 atf_check -s exit:0 -o ignore \ 326 ping6 -c 1 64:ff9b::192.0.2.2 327 328 rcv=$(echo bar | nc --sctp -w 3 -6 64:ff9b::c000:202 1234) 329 if [ "${rcv}" != "foo" ]; 330 then 331 echo "rcv=${rcv}" 332 atf_fail "Failed to connect to SCTP server" 333 fi 334} 335 336sctp_in_cleanup() 337{ 338 pft_cleanup 339} 340 341atf_test_case "sctp_out" "cleanup" 342sctp_out_head() 343{ 344 atf_set descr 'SCTP NAT64 test on outbound interface' 345 atf_set require.user root 346} 347 348sctp_out_body() 349{ 350 nat64_setup_out 351 if ! kldstat -q -m sctp; then 352 atf_skip "This test requires SCTP" 353 fi 354 355 echo "foo" | jexec dst nc --sctp -N -l 1234 & 356 357 # Sanity check & delay for nc startup 358 atf_check -s exit:0 -o ignore \ 359 ping6 -c 1 64:ff9b::192.0.2.2 360 361 rcv=$(echo bar | nc --sctp -w 3 -6 64:ff9b::c000:202 1234) 362 if [ "${rcv}" != "foo" ]; 363 then 364 echo "rcv=${rcv}" 365 atf_fail "Failed to connect to SCTP server" 366 fi 367} 368 369sctp_out_cleanup() 370{ 371 pft_cleanup 372} 373 374atf_test_case "tos" "cleanup" 375tos_head() 376{ 377 atf_set descr 'ToS translation test' 378 atf_set require.user root 379} 380 381tos_body() 382{ 383 nat64_setup_in 384 385 # Ensure we can distinguish ToS on the destination 386 jexec dst pfctl -e 387 pft_set_rules dst \ 388 "pass" \ 389 "block in inet tos 8" 390 391 atf_check -s exit:0 -o ignore \ 392 ping6 -c 1 -z 4 64:ff9b::192.0.2.2 393 atf_check -s exit:2 -o ignore \ 394 ping6 -c 1 -z 8 64:ff9b::192.0.2.2 395 atf_check -s exit:0 -o ignore \ 396 ping6 -c 1 -z 16 64:ff9b::192.0.2.2 397 398 jexec dst pfctl -sr -vv 399} 400 401tos_cleanup() 402{ 403 pft_cleanup 404} 405 406atf_test_case "no_v4" "cleanup" 407no_v4_head() 408{ 409 atf_set descr 'Test error handling when there is no IPv4 address to translate to' 410 atf_set require.user root 411} 412 413no_v4_body() 414{ 415 pft_init 416 417 epair_link=$(vnet_mkepair) 418 epair=$(vnet_mkepair) 419 420 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 421 route -6 add default 2001:db8::1 422 423 vnet_mkjail rtr ${epair}b ${epair_link}a 424 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 425 426 vnet_mkjail dst ${epair_link}b 427 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 428 jexec dst route add default 192.0.2.1 429 430 # Sanity check 431 atf_check -s exit:0 -o ignore \ 432 ping6 -c 1 2001:db8::1 433 434 jexec rtr pfctl -e 435 pft_set_rules rtr \ 436 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" 437 438 atf_check -s exit:2 -o ignore \ 439 ping6 -c 3 64:ff9b::192.0.2.2 440} 441 442no_v4_cleanup() 443{ 444 pft_cleanup 445} 446 447atf_test_case "range" "cleanup" 448range_head() 449{ 450 atf_set descr 'Test using an address range for the IPv4 side' 451 atf_set require.user root 452} 453 454range_body() 455{ 456 pft_init 457 458 epair_link=$(vnet_mkepair) 459 epair=$(vnet_mkepair) 460 461 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 462 route -6 add default 2001:db8::1 463 464 vnet_mkjail rtr ${epair}b ${epair_link}a 465 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 466 jexec rtr ifconfig ${epair_link}a 192.0.2.2/24 up 467 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.3/24 up 468 469 vnet_mkjail dst ${epair_link}b 470 jexec dst ifconfig ${epair_link}b 192.0.2.254/24 up 471 jexec dst route add default 192.0.2.2 472 473 # Sanity checks 474 atf_check -s exit:0 -o ignore \ 475 jexec rtr ping -c 1 192.0.2.254 476 atf_check -s exit:0 -o ignore \ 477 ping6 -c 1 2001:db8::1 478 atf_check -s exit:0 -o ignore \ 479 jexec dst ping -c 1 192.0.2.2 480 atf_check -s exit:0 -o ignore \ 481 jexec dst ping -c 1 192.0.2.3 482 483 jexec rtr pfctl -e 484 pft_set_rules rtr \ 485 "set reassemble yes" \ 486 "set state-policy if-bound" \ 487 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from 192.0.2.2/31 round-robin" 488 489 # Use pf to count sources 490 jexec dst pfctl -e 491 pft_set_rules dst \ 492 "pass" 493 494 atf_check -s exit:0 -o ignore \ 495 ping6 -c 1 64:ff9b::192.0.2.254 496 atf_check -s exit:0 -o ignore \ 497 ping6 -c 1 64:ff9b::192.0.2.254 498 499 # Verify on dst that we saw different source addresses 500 atf_check -s exit:0 -o match:".*192.0.2.2.*" \ 501 jexec dst pfctl -ss 502 atf_check -s exit:0 -o match:".*192.0.2.3.*" \ 503 jexec dst pfctl -ss 504} 505 506range_cleanup() 507{ 508 pft_cleanup 509} 510 511atf_test_case "pool" "cleanup" 512pool_head() 513{ 514 atf_set descr 'Use a pool of IPv4 addresses' 515 atf_set require.user root 516} 517 518pool_body() 519{ 520 pft_init 521 522 epair_link=$(vnet_mkepair) 523 epair=$(vnet_mkepair) 524 525 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 526 route -6 add default 2001:db8::1 527 528 vnet_mkjail rtr ${epair}b ${epair_link}a 529 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 530 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 531 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.3/24 up 532 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.4/24 up 533 534 vnet_mkjail dst ${epair_link}b 535 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 536 jexec dst route add default 192.0.2.1 537 538 # Sanity checks 539 atf_check -s exit:0 -o ignore \ 540 ping6 -c 1 2001:db8::1 541 atf_check -s exit:0 -o ignore \ 542 jexec dst ping -c 1 192.0.2.1 543 544 jexec rtr pfctl -e 545 pft_set_rules rtr \ 546 "set reassemble yes" \ 547 "set state-policy if-bound" \ 548 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from { 192.0.2.1, 192.0.2.3, 192.0.2.4 } round-robin" 549 550 # Use pf to count sources 551 jexec dst pfctl -e 552 pft_set_rules dst \ 553 "pass" 554 555 atf_check -s exit:0 -o ignore \ 556 ping6 -c 1 64:ff9b::192.0.2.2 557 atf_check -s exit:0 -o ignore \ 558 ping6 -c 1 64:ff9b::192.0.2.2 559 atf_check -s exit:0 -o ignore \ 560 ping6 -c 1 64:ff9b::192.0.2.2 561 562 # Verify on dst that we saw different source addresses 563 atf_check -s exit:0 -o match:".*192.0.2.1.*" \ 564 jexec dst pfctl -ss 565 atf_check -s exit:0 -o match:".*192.0.2.3.*" \ 566 jexec dst pfctl -ss 567 atf_check -s exit:0 -o match:".*192.0.2.4.*" \ 568 jexec dst pfctl -ss 569} 570 571pool_cleanup() 572{ 573 pft_cleanup 574} 575 576 577atf_test_case "table" 578table_head() 579{ 580 atf_set descr 'Check table restrictions' 581 atf_set require.user root 582} 583 584table_body() 585{ 586 pft_init 587 588 # Round-robin and random are allowed 589 echo "pass in on epair inet6 from any to 64:ff9b::/96 af-to inet from <wanaddr> round-robin" | \ 590 atf_check -s exit:0 \ 591 pfctl -f - 592 echo "pass in on epair inet6 from any to 64:ff9b::/96 af-to inet from <wanaddr> random" | \ 593 atf_check -s exit:0 \ 594 pfctl -f - 595 596 # bitmask is not 597 echo "pass in on epair inet6 from any to 64:ff9b::/96 af-to inet from <wanaddr> bitmask" | \ 598 atf_check -s exit:1 \ 599 -e match:"tables are not supported by pool type" \ 600 pfctl -f - 601} 602 603table_cleanup() 604{ 605 pft_cleanup 606} 607 608atf_test_case "table_range" "cleanup" 609table_range_head() 610{ 611 atf_set descr 'Test using an address range within a table for the IPv4 side' 612 atf_set require.user root 613} 614 615table_range_body() 616{ 617 pft_init 618 619 epair_link=$(vnet_mkepair) 620 epair=$(vnet_mkepair) 621 622 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 623 route -6 add default 2001:db8::1 624 625 vnet_mkjail rtr ${epair}b ${epair_link}a 626 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 627 jexec rtr ifconfig ${epair_link}a 192.0.2.2/24 up 628 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.3/24 up 629 630 vnet_mkjail dst ${epair_link}b 631 jexec dst ifconfig ${epair_link}b 192.0.2.254/24 up 632 jexec dst route add default 192.0.2.2 633 634 # Sanity checks 635 atf_check -s exit:0 -o ignore \ 636 ping6 -c 1 2001:db8::1 637 atf_check -s exit:0 -o ignore \ 638 jexec dst ping -c 1 192.0.2.2 639 640 jexec rtr pfctl -e 641 pft_set_rules rtr \ 642 "set reassemble yes" \ 643 "set state-policy if-bound" \ 644 "table <wanaddrs> { 192.0.2.2/31 }" \ 645 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from <wanaddrs> round-robin" 646 647 # Use pf to count sources 648 jexec dst pfctl -e 649 pft_set_rules dst \ 650 "pass" 651 652 atf_check -s exit:0 -o ignore \ 653 ping6 -c 1 64:ff9b::192.0.2.254 654 atf_check -s exit:0 -o ignore \ 655 ping6 -c 1 64:ff9b::192.0.2.254 656 657 # Verify on dst that we saw different source addresses 658 atf_check -s exit:0 -o match:".*192.0.2.2.*" \ 659 jexec dst pfctl -ss 660 atf_check -s exit:0 -o match:".*192.0.2.3.*" \ 661 jexec dst pfctl -ss 662} 663 664table_range_cleanup() 665{ 666 pft_cleanup 667} 668 669table_common_body() 670{ 671 pool_type=$1 672 673 pft_init 674 675 epair_link=$(vnet_mkepair) 676 epair=$(vnet_mkepair) 677 678 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 679 route -6 add default 2001:db8::1 680 681 vnet_mkjail rtr ${epair}b ${epair_link}a 682 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 683 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 684 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.3/24 up 685 jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.4/24 up 686 687 vnet_mkjail dst ${epair_link}b 688 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 689 jexec dst route add default 192.0.2.1 690 691 # Sanity checks 692 atf_check -s exit:0 -o ignore \ 693 ping6 -c 1 2001:db8::1 694 atf_check -s exit:0 -o ignore \ 695 jexec dst ping -c 1 192.0.2.1 696 697 jexec rtr pfctl -e 698 pft_set_rules rtr \ 699 "set reassemble yes" \ 700 "set state-policy if-bound" \ 701 "table <wanaddrs> { 192.0.2.1, 192.0.2.3, 192.0.2.4 }" \ 702 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from <wanaddrs> ${pool_type}" 703 704 # Use pf to count sources 705 jexec dst pfctl -e 706 pft_set_rules dst \ 707 "pass" 708 709 atf_check -s exit:0 -o ignore \ 710 ping6 -c 1 64:ff9b::192.0.2.2 711 atf_check -s exit:0 -o ignore \ 712 ping6 -c 1 64:ff9b::192.0.2.2 713 atf_check -s exit:0 -o ignore \ 714 ping6 -c 1 64:ff9b::192.0.2.2 715 716 # XXX We can't reasonably check pool type random because it's random. It may end 717 # up choosing the same source IP for all three connections. 718 if [ "${pool_type}" == "round-robin" ]; 719 then 720 # Verify on dst that we saw different source addresses 721 atf_check -s exit:0 -o match:".*192.0.2.1.*" \ 722 jexec dst pfctl -ss 723 atf_check -s exit:0 -o match:".*192.0.2.3.*" \ 724 jexec dst pfctl -ss 725 atf_check -s exit:0 -o match:".*192.0.2.4.*" \ 726 jexec dst pfctl -ss 727 fi 728} 729 730atf_test_case "table_round_robin" "cleanup" 731table_round_robin_head() 732{ 733 atf_set descr 'Use a table of IPv4 addresses in round-robin mode' 734 atf_set require.user root 735} 736 737table_round_robin_body() 738{ 739 table_common_body round-robin 740} 741 742table_round_robin_cleanup() 743{ 744 pft_cleanup 745} 746 747atf_test_case "table_random" "cleanup" 748table_random_head() 749{ 750 atf_set descr 'Use a table of IPv4 addresses in random mode' 751 atf_set require.user root 752} 753 754table_random_body() 755{ 756 table_common_body random 757} 758 759table_random_cleanup() 760{ 761 pft_cleanup 762} 763 764atf_test_case "dummynet" "cleanup" 765dummynet_head() 766{ 767 atf_set descr 'Test dummynet on af-to rules' 768 atf_set require.user root 769} 770 771dummynet_body() 772{ 773 pft_init 774 dummynet_init 775 776 epair_link=$(vnet_mkepair) 777 epair=$(vnet_mkepair) 778 779 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 780 route -6 add default 2001:db8::1 781 782 vnet_mkjail rtr ${epair}b ${epair_link}a 783 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 784 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 785 786 vnet_mkjail dst ${epair_link}b 787 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 788 jexec dst route add default 192.0.2.1 789 790 # Sanity checks 791 atf_check -s exit:0 -o ignore \ 792 ping6 -c 1 2001:db8::1 793 atf_check -s exit:0 -o ignore \ 794 jexec dst ping -c 1 192.0.2.1 795 796 jexec rtr pfctl -e 797 jexec rtr dnctl pipe 1 config delay 600 798 pft_set_rules rtr \ 799 "set reassemble yes" \ 800 "set state-policy if-bound" \ 801 "pass in on ${epair}b inet6 from any to 64:ff9b::/96 dnpipe 1 af-to inet from (${epair_link}a)" 802 803 # The ping request will pass, but take 1.2 seconds (.6 in, .6 out) 804 # So this works: 805 atf_check -s exit:0 -o ignore \ 806 ping6 -c 1 -t 2 64:ff9b::192.0.2.2 807 808 # But this times out: 809 atf_check -s exit:2 -o ignore \ 810 ping6 -c 1 -t 1 64:ff9b::192.0.2.2 811} 812 813dummynet_cleanup() 814{ 815 pft_cleanup 816} 817 818atf_test_case "gateway6" "cleanup" 819gateway6_head() 820{ 821 atf_set descr 'NAT64 with a routing hop on the v6 side' 822 atf_set require.user root 823} 824 825gateway6_body() 826{ 827 pft_init 828 829 epair_lan_link=$(vnet_mkepair) 830 epair_link=$(vnet_mkepair) 831 epair=$(vnet_mkepair) 832 833 ifconfig ${epair}a inet6 2001:db8:1::2/64 up no_dad 834 route -6 add default 2001:db8:1::1 835 836 vnet_mkjail lan_rtr ${epair}b ${epair_lan_link}a 837 jexec lan_rtr ifconfig ${epair}b inet6 2001:db8:1::1/64 up no_dad 838 jexec lan_rtr ifconfig ${epair_lan_link}a inet6 2001:db8::2/64 up no_dad 839 jexec lan_rtr route -6 add default 2001:db8::1 840 jexec lan_rtr sysctl net.inet6.ip6.forwarding=1 841 842 vnet_mkjail rtr ${epair_lan_link}b ${epair_link}a 843 jexec rtr ifconfig ${epair_lan_link}b inet6 2001:db8::1/64 up no_dad 844 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 845 jexec rtr route -6 add default 2001:db8::2 846 847 vnet_mkjail dst ${epair_link}b 848 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 849 jexec dst route add default 192.0.2.1 850 851 # Sanity checks 852 atf_check -s exit:0 -o ignore \ 853 ping6 -c 1 2001:db8:1::1 854 atf_check -s exit:0 -o ignore \ 855 ping6 -c 1 2001:db8::1 856 atf_check -s exit:0 -o ignore \ 857 jexec dst ping -c 1 192.0.2.1 858 859 jexec rtr pfctl -e 860 pft_set_rules rtr \ 861 "set reassemble yes" \ 862 "set state-policy if-bound" \ 863 "pass in on ${epair_lan_link}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" 864 865 # One ping 866 atf_check -s exit:0 -o ignore \ 867 ping6 -c 1 64:ff9b::192.0.2.2 868 869 # Make sure packets make it even when state is established 870 atf_check -s exit:0 \ 871 -o match:'5 packets transmitted, 5 packets received, 0.0% packet loss' \ 872 ping6 -c 5 64:ff9b::192.0.2.2 873} 874 875gateway6_cleanup() 876{ 877 pft_cleanup 878} 879 880atf_test_case "route_to" "cleanup" 881route_to_head() 882{ 883 atf_set descr 'Test route-to on af-to rules' 884 atf_set require.user root 885} 886 887route_to_body() 888{ 889 pft_init 890 891 epair_link=$(vnet_mkepair) 892 epair_null=$(vnet_mkepair) 893 epair=$(vnet_mkepair) 894 895 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 896 route -6 add default 2001:db8::1 897 898 vnet_mkjail rtr ${epair}b ${epair_link}a ${epair_null}a 899 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 900 jexec rtr ifconfig ${epair_null}a 192.0.2.3/24 up 901 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 902 903 vnet_mkjail dst ${epair_link}b 904 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 905 jexec dst route add default 192.0.2.1 906 907 # Sanity checks 908 atf_check -s exit:0 -o ignore \ 909 ping6 -c 1 2001:db8::1 910 911 jexec rtr pfctl -e 912 pft_set_rules rtr \ 913 "set reassemble yes" \ 914 "set state-policy if-bound" \ 915 "pass in on ${epair}b route-to (${epair_link}a 192.0.2.2) inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" 916 917 atf_check -s exit:0 -o ignore \ 918 ping6 -c 3 64:ff9b::192.0.2.2 919} 920 921route_to_cleanup() 922{ 923 pft_cleanup 924} 925 926atf_test_case "reply_to" "cleanup" 927reply_to_head() 928{ 929 atf_set descr 'Test reply-to on af-to rules' 930 atf_set require.user root 931} 932 933reply_to_body() 934{ 935 pft_init 936 937 epair_link=$(vnet_mkepair) 938 epair=$(vnet_mkepair) 939 940 ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad 941 route -6 add default 2001:db8::1 942 943 vnet_mkjail rtr ${epair}b ${epair_link}a 944 jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad 945 jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up 946 947 vnet_mkjail dst ${epair_link}b 948 jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up 949 jexec dst route add default 192.0.2.1 950 951 # Sanity checks 952 atf_check -s exit:0 -o ignore \ 953 ping6 -c 1 2001:db8::1 954 955 jexec rtr pfctl -e 956 pft_set_rules rtr \ 957 "set reassemble yes" \ 958 "set state-policy if-bound" \ 959 "pass in on ${epair}b reply-to (${epair}b 2001:db8::2) inet6 from any to 64:ff9b::/96 af-to inet from 192.0.2.1" 960 961 atf_check -s exit:0 -o ignore \ 962 ping6 -c 3 64:ff9b::192.0.2.2 963} 964 965reply_to_cleanup() 966{ 967 pft_cleanup 968} 969 970atf_test_case "v6_gateway" "cleanup" 971v6_gateway_head() 972{ 973 atf_set descr 'nat64 when the IPv4 gateway is given by an IPv6 address' 974 atf_set require.user root 975} 976 977v6_gateway_body() 978{ 979 pft_init 980 981 epair_wan_two=$(vnet_mkepair) 982 epair_wan_one=$(vnet_mkepair) 983 epair_lan=$(vnet_mkepair) 984 985 ifconfig ${epair_lan}a inet6 2001:db8::2/64 up no_dad 986 route -6 add default 2001:db8::1 987 988 vnet_mkjail rtr ${epair_lan}b ${epair_wan_one}a 989 jexec rtr ifconfig ${epair_lan}b inet6 2001:db8::1/64 up no_dad 990 jexec rtr ifconfig ${epair_wan_one}a 192.0.2.1/24 up 991 jexec rtr ifconfig ${epair_wan_one}a inet6 -ifdisabled 992 jexec rtr route add default -inet6 fe80::1%${epair_wan_one}a 993 #jexec rtr route add default 192.0.2.2 994 995 vnet_mkjail wan_one ${epair_wan_one}b ${epair_wan_two}a 996 jexec wan_one ifconfig ${epair_wan_one}b 192.0.2.2/24 up 997 jexec wan_one ifconfig ${epair_wan_one}b inet6 fe80::1/64 998 jexec wan_one ifconfig ${epair_wan_two}a 198.51.100.2/24 up 999 jexec wan_one route add default 192.0.2.1 1000 jexec wan_one sysctl net.inet.ip.forwarding=1 1001 1002 vnet_mkjail wan_two ${epair_wan_two}b 1003 jexec wan_two ifconfig ${epair_wan_two}b 198.51.100.1/24 up 1004 jexec wan_two route add default 198.51.100.2 1005 1006 # Sanity checks 1007 atf_check -s exit:0 -o ignore \ 1008 ping6 -c 1 2001:db8::1 1009 atf_check -s exit:0 -o ignore \ 1010 jexec rtr ping -c 1 192.0.2.2 1011 atf_check -s exit:0 -o ignore \ 1012 jexec rtr ping -c 1 198.51.100.1 1013 1014 jexec rtr pfctl -e 1015 pft_set_rules rtr \ 1016 "set reassemble yes" \ 1017 "set state-policy if-bound" \ 1018 "pass in on ${epair_lan}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_wan_one}a)" 1019 1020 atf_check -s exit:0 -o ignore \ 1021 ping6 -c 3 64:ff9b::192.0.2.2 1022 atf_check -s exit:0 -o ignore \ 1023 ping6 -c 3 64:ff9b::198.51.100.1 1024} 1025 1026v6_gateway_cleanup() 1027{ 1028 pft_cleanup 1029} 1030 1031atf_init_test_cases() 1032{ 1033 atf_add_test_case "icmp_echo_in" 1034 atf_add_test_case "icmp_echo_out" 1035 atf_add_test_case "fragmentation_in" 1036 atf_add_test_case "fragmentation_out" 1037 atf_add_test_case "tcp_in" 1038 atf_add_test_case "tcp_out" 1039 atf_add_test_case "udp_in" 1040 atf_add_test_case "udp_out" 1041 atf_add_test_case "sctp_in" 1042 atf_add_test_case "sctp_out" 1043 atf_add_test_case "tos" 1044 atf_add_test_case "no_v4" 1045 atf_add_test_case "range" 1046 atf_add_test_case "pool" 1047 atf_add_test_case "table" 1048 atf_add_test_case "table_range" 1049 atf_add_test_case "table_round_robin" 1050 atf_add_test_case "table_random" 1051 atf_add_test_case "dummynet" 1052 atf_add_test_case "gateway6" 1053 atf_add_test_case "route_to" 1054 atf_add_test_case "reply_to" 1055 atf_add_test_case "v6_gateway" 1056} 1057