1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2020 Mark Johnston <markj@FreeBSD.org> 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 29TABLE_STATS_ZERO_REGEXP='Packets: 0[[:space:]]*Bytes: 0[[:space:]]' 30TABLE_STATS_NONZERO_REGEXP='Packets: [1-9][0-9]*[[:space:]]*Bytes: [1-9][0-9]*[[:space:]]' 31 32atf_test_case "v4_counters" "cleanup" 33v4_counters_head() 34{ 35 atf_set descr 'Verify per-address counters for v4' 36 atf_set require.user root 37} 38 39v4_counters_body() 40{ 41 pft_init 42 43 epair_send=$(vnet_mkepair) 44 ifconfig ${epair_send}a 192.0.2.1/24 up 45 46 vnet_mkjail alcatraz ${epair_send}b 47 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 48 jexec alcatraz pfctl -e 49 50 pft_set_rules alcatraz \ 51 "table <foo> counters { 192.0.2.1 }" \ 52 "block all" \ 53 "pass in from <foo> to any" \ 54 "pass out from any to <foo>" \ 55 "set skip on lo" 56 57 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 58 59 atf_check -s exit:0 -e ignore \ 60 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 61 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 62 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 63 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 64 jexec alcatraz pfctl -t foo -T show -vv 65} 66 67v4_counters_cleanup() 68{ 69 pft_cleanup 70} 71 72atf_test_case "v6_counters" "cleanup" 73v6_counters_head() 74{ 75 atf_set descr 'Verify per-address counters for v6' 76 atf_set require.user root 77} 78 79v6_counters_body() 80{ 81 pft_init 82 83 epair_send=$(vnet_mkepair) 84 ifconfig ${epair_send}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled 85 86 vnet_mkjail alcatraz ${epair_send}b 87 jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 up no_dad 88 jexec alcatraz pfctl -e 89 90 pft_set_rules alcatraz \ 91 "table <foo6> counters { 2001:db8:42::1 }" \ 92 "block all" \ 93 "pass in from <foo6> to any" \ 94 "pass out from any to <foo6>" \ 95 "set skip on lo" 96 97 atf_check -s exit:0 -o ignore ping -6 -c 3 2001:db8:42::2 98 99 atf_check -s exit:0 -e ignore \ 100 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 101 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 102 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 103 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 104 jexec alcatraz pfctl -t foo6 -T show -vv 105} 106 107v6_counters_cleanup() 108{ 109 pft_cleanup 110} 111 112atf_test_case "match_counters" "cleanup" 113match_counters_head() 114{ 115 atf_set descr 'Test that counters for tables in match rules work' 116 atf_set require.user root 117} 118 119match_counters_body() 120{ 121 pft_init 122 123 epair_send=$(vnet_mkepair) 124 ifconfig ${epair_send}a 192.0.2.1/24 up 125 126 vnet_mkjail alcatraz ${epair_send}b 127 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 128 jexec alcatraz pfctl -e 129 130 pft_set_rules alcatraz \ 131 "table <foo> counters { 192.0.2.1 }" \ 132 "pass all" \ 133 "match in from <foo> to any" \ 134 "match out from any to <foo>" \ 135 "set skip on lo" 136 137 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 138 139 atf_check -s exit:0 -e ignore \ 140 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 141 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 142 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 143 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 144 jexec alcatraz pfctl -t foo -T show -vv 145} 146 147match_counters_cleanup() 148{ 149 pft_cleanup 150} 151 152atf_test_case "zero_one" "cleanup" 153zero_one_head() 154{ 155 atf_set descr 'Test zeroing a single address in a table' 156 atf_set require.user root 157} 158 159pft_cleared_ctime() 160{ 161 jexec "$1" pfctl -t "$2" -vvT show | awk -v ip="$3" ' 162 ($1 == ip) { m = 1 } 163 ($1 == "Cleared:" && m) { 164 sub("[[:space:]]*Cleared:[[:space:]]*", ""); print; exit }' 165} 166 167ctime_to_unixtime() 168{ 169 # NB: it's not TZ=UTC, it's TZ=/etc/localtime 170 date -jf '%a %b %d %H:%M:%S %Y' "$1" '+%s' 171} 172 173zero_one_body() 174{ 175 pft_init 176 177 epair_send=$(vnet_mkepair) 178 ifconfig ${epair_send}a 192.0.2.1/24 up 179 ifconfig ${epair_send}a inet alias 192.0.2.3/24 180 181 vnet_mkjail alcatraz ${epair_send}b 182 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 183 jexec alcatraz pfctl -e 184 185 pft_set_rules alcatraz \ 186 "table <foo> counters { 192.0.2.1, 192.0.2.3 }" \ 187 "block all" \ 188 "pass in from <foo> to any" \ 189 "pass out from any to <foo>" \ 190 "set skip on lo" 191 192 atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.1 192.0.2.2 193 atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.3 192.0.2.2 194 195 jexec alcatraz pfctl -t foo -T show -vv 196 197 atf_check -s exit:0 -e ignore \ 198 -o match:'Addresses: 2' \ 199 jexec alcatraz pfctl -vvsTables 200 201 atf_check -s exit:0 -e ignore \ 202 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 203 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 204 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 205 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 206 jexec alcatraz pfctl -t foo -T show -vv 207 208 local uniq base ts1 ts3 209 uniq=`jexec alcatraz pfctl -t foo -vvT show | sort -u | grep -c Cleared` 210 atf_check_equal 1 "$uniq" # time they were added 211 212 base=`pft_cleared_ctime alcatraz foo 192.0.2.1` 213 214 atf_check -s exit:0 -e ignore \ 215 jexec alcatraz pfctl -t foo -T zero 192.0.2.3 216 217 ts1=`pft_cleared_ctime alcatraz foo 192.0.2.1` 218 atf_check_equal "$base" "$ts1" 219 220 ts3=`pft_cleared_ctime alcatraz foo 192.0.2.3` 221 atf_check test "$ts1" != "$ts3" 222 223 ts1=`ctime_to_unixtime "$ts1"` 224 ts3=`ctime_to_unixtime "$ts3"` 225 atf_check test $(( "$ts3" - "$ts1" )) -lt 10 # (3 pings * 2) + epsilon 226 atf_check test "$ts1" -lt "$ts3" 227 228 # We now have a zeroed and a non-zeroed counter, so both patterns 229 # should match 230 atf_check -s exit:0 -e ignore \ 231 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 232 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 233 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 234 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 235 jexec alcatraz pfctl -t foo -T show -vv 236} 237 238zero_one_cleanup() 239{ 240 pft_cleanup 241} 242 243atf_test_case "zero_all" "cleanup" 244zero_all_head() 245{ 246 atf_set descr 'Test zeroing all table entries' 247 atf_set require.user root 248} 249 250zero_all_body() 251{ 252 pft_init 253 254 epair_send=$(vnet_mkepair) 255 ifconfig ${epair_send}a 192.0.2.1/24 up 256 ifconfig ${epair_send}a inet alias 192.0.2.3/24 257 258 vnet_mkjail alcatraz ${epair_send}b 259 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 260 jexec alcatraz pfctl -e 261 262 pft_set_rules alcatraz \ 263 "table <foo> counters { 192.0.2.1, 192.0.2.3 }" \ 264 "block all" \ 265 "pass in from <foo> to any" \ 266 "pass out from any to <foo>" \ 267 "set skip on lo" 268 269 atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.1 192.0.2.2 270 atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.3 192.0.2.2 271 272 jexec alcatraz pfctl -t foo -T show -vv 273 atf_check -s exit:0 -e ignore \ 274 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 275 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 276 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 277 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 278 jexec alcatraz pfctl -t foo -T show -vv 279 280 atf_check -s exit:0 -e ignore \ 281 jexec alcatraz pfctl -t foo -T zero 282 283 jexec alcatraz pfctl -t foo -T show -vv 284 atf_check -s exit:0 -e ignore \ 285 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 286 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 287 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 288 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 289 jexec alcatraz pfctl -t foo -T show -vv 290} 291 292zero_all_cleanup() 293{ 294 pft_cleanup 295} 296 297atf_test_case "reset_nonzero" "cleanup" 298reset_nonzero_head() 299{ 300 atf_set descr 'Test zeroing an address with non-zero counters' 301 atf_set require.user root 302} 303 304reset_nonzero_body() 305{ 306 pft_init 307 308 epair_send=$(vnet_mkepair) 309 ifconfig ${epair_send}a 192.0.2.1/24 up 310 ifconfig ${epair_send}a inet alias 192.0.2.3/24 311 312 vnet_mkjail alcatraz ${epair_send}b 313 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 314 jexec alcatraz pfctl -e 315 316 pft_set_rules alcatraz \ 317 "table <foo> counters { 192.0.2.1, 192.0.2.3 }" \ 318 "table <bar> counters { }" \ 319 "block all" \ 320 "pass in from <foo> to any" \ 321 "pass out from any to <foo>" \ 322 "pass on notReallyAnIf from <bar> to <bar>" \ 323 "set skip on lo" 324 325 # Nonexisting table can't be reset, following `-T show`. 326 atf_check -o ignore \ 327 -s not-exit:0 \ 328 -e inline:"pfctl: Table does not exist.\n" \ 329 jexec alcatraz pfctl -t nonexistent -T reset 330 331 atf_check -o ignore \ 332 -s exit:0 \ 333 -e inline:"0/0 stats cleared.\n" \ 334 jexec alcatraz pfctl -t bar -T reset 335 336 # No-op is a valid operation. 337 atf_check -s exit:0 \ 338 -e inline:"0/2 stats cleared.\n" \ 339 jexec alcatraz pfctl -t foo -T reset 340 341 atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.3 192.0.2.2 342 343 atf_check -s exit:0 -e ignore \ 344 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 345 -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 346 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 347 -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 348 jexec alcatraz pfctl -t foo -vvT show 349 350 local clrd uniq 351 clrd=`jexec alcatraz pfctl -t foo -vvT show | grep -c Cleared` 352 uniq=`jexec alcatraz pfctl -t foo -vvT show | sort -u | grep -c Cleared` 353 atf_check_equal "$clrd" 2 354 atf_check_equal "$uniq" 1 # time they were added 355 356 atf_check -s exit:0 -e ignore \ 357 -e inline:"1/2 stats cleared.\n" \ 358 jexec alcatraz pfctl -t foo -T reset 359 360 clrd=`jexec alcatraz pfctl -t foo -vvT show | grep -c Cleared` 361 uniq=`jexec alcatraz pfctl -t foo -vvT show | sort -u | grep -c Cleared` 362 atf_check_equal "$clrd" 2 363 atf_check_equal "$uniq" 2 # 192.0.2.3 should get new timestamp 364 365 atf_check -s exit:0 -e ignore \ 366 -o not-match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 367 -o not-match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ 368 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 369 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 370 jexec alcatraz pfctl -t foo -vvT show 371} 372 373reset_nonzero_cleanup() 374{ 375 pft_cleanup 376} 377 378atf_test_case "pr251414" "cleanup" 379pr251414_head() 380{ 381 atf_set descr 'Test PR 251414' 382 atf_set require.user root 383} 384 385pr251414_body() 386{ 387 pft_init 388 389 epair_send=$(vnet_mkepair) 390 ifconfig ${epair_send}a 192.0.2.1/24 up 391 392 vnet_mkjail alcatraz ${epair_send}b 393 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 394 jexec alcatraz pfctl -e 395 396 pft_set_rules alcatraz \ 397 "pass all" \ 398 "table <tab> { self }" \ 399 "pass in log to <tab>" 400 401 pft_set_rules noflush alcatraz \ 402 "pass all" \ 403 "table <tab> counters { self }" \ 404 "pass in log to <tab>" 405 406 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 407 408 jexec alcatraz pfctl -t tab -T show -vv 409} 410 411pr251414_cleanup() 412{ 413 pft_cleanup 414} 415 416atf_test_case "automatic" "cleanup" 417automatic_head() 418{ 419 atf_set descr "Test automatic - optimizer generated - tables" 420 atf_set require.user root 421} 422 423automatic_body() 424{ 425 pft_init 426 427 epair=$(vnet_mkepair) 428 ifconfig ${epair}a 192.0.2.1/24 up 429 430 vnet_mkjail alcatraz ${epair}b 431 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 432 jexec alcatraz pfctl -e 433 434 pft_set_rules alcatraz \ 435 "block in" \ 436 "pass in proto icmp from 192.0.2.1" \ 437 "pass in proto icmp from 192.0.2.3" \ 438 "pass in proto icmp from 192.0.2.4" \ 439 "pass in proto icmp from 192.0.2.5" \ 440 "pass in proto icmp from 192.0.2.6" \ 441 "pass in proto icmp from 192.0.2.7" \ 442 "pass in proto icmp from 192.0.2.8" \ 443 "pass in proto icmp from 192.0.2.9" 444 445 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 446} 447 448automatic_cleanup() 449{ 450 pft_cleanup 451} 452 453atf_test_case "network" "cleanup" 454network_head() 455{ 456 atf_set descr 'Test <ifgroup>:network' 457 atf_set require.user root 458} 459 460network_body() 461{ 462 pft_init 463 464 epair=$(vnet_mkepair) 465 ifconfig ${epair}a 192.0.2.1/24 up 466 467 vnet_mkjail alcatraz ${epair}b 468 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 469 jexec alcatraz pfctl -e 470 471 pft_set_rules alcatraz \ 472 "table <allow> const { epair:network }"\ 473 "block in" \ 474 "pass in from <allow>" 475 476 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 477} 478 479network_cleanup() 480{ 481 pft_cleanup 482} 483 484atf_test_case "pr259689" "cleanup" 485pr259689_head() 486{ 487 atf_set descr 'Test PR 259689' 488 atf_set require.user root 489} 490 491pr259689_body() 492{ 493 pft_init 494 495 vnet_mkjail alcatraz 496 jexec alcatraz pfctl -e 497 498 pft_set_rules alcatraz \ 499 "pass in" \ 500 "block in inet from { 1.1.1.1, 1.1.1.2, 2.2.2.2, 2.2.2.3, 4.4.4.4, 4.4.4.5 }" 501 502 atf_check -o match:'block drop in inet from <__automatic_.*:6> to any' \ 503 -e ignore \ 504 jexec alcatraz pfctl -sr -vv 505} 506 507pr259689_cleanup() 508{ 509 pft_cleanup 510} 511 512atf_test_case "precreate" "cleanup" 513precreate_head() 514{ 515 atf_set descr 'Test creating a table without counters, then loading rules that add counters' 516 atf_set require.user root 517} 518 519precreate_body() 520{ 521 pft_init 522 523 vnet_mkjail alcatraz 524 525 jexec alcatraz pfctl -t foo -T add 192.0.2.1 526 jexec alcatraz pfctl -t foo -T show 527 528 pft_set_rules noflush alcatraz \ 529 "table <foo> counters persist" \ 530 "pass in from <foo>" 531 532 # Expect all counters to be zero 533 atf_check -s exit:0 -e ignore \ 534 -o match:'In/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 535 -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 536 -o match:'Out/Block:.*'"$TABLE_STATS_ZERO_REGEXP" \ 537 -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ 538 jexec alcatraz pfctl -t foo -T show -vv 539 540} 541 542precreate_cleanup() 543{ 544 pft_cleanup 545} 546 547atf_test_case "anchor" "cleanup" 548anchor_head() 549{ 550 atf_set descr 'Test tables in anchors' 551 atf_set require.user root 552} 553 554anchor_body() 555{ 556 pft_init 557 558 epair=$(vnet_mkepair) 559 ifconfig ${epair}a 192.0.2.1/24 up 560 561 vnet_mkjail alcatraz ${epair}b 562 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 563 jexec alcatraz pfctl -e 564 565 (echo "table <testtable> persist" 566 echo "block in quick from <testtable> to any" 567 ) | jexec alcatraz pfctl -a anchorage -f - 568 569 pft_set_rules noflush alcatraz \ 570 "pass" \ 571 "anchor anchorage" 572 573 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 574 575 # Tables belong to anchors, so this is a different table and won't affect anything 576 jexec alcatraz pfctl -t testtable -T add 192.0.2.1 577 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 578 579 # But when we add the address to the table in the anchor it does block traffic 580 jexec alcatraz pfctl -a anchorage -t testtable -T add 192.0.2.1 581 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 582} 583 584anchor_cleanup() 585{ 586 pft_cleanup 587} 588 589atf_test_case "flush" "cleanup" 590flush_head() 591{ 592 atf_set descr 'Test flushing addresses from tables' 593 atf_set require.user root 594} 595 596flush_body() 597{ 598 pft_init 599 600 vnet_mkjail alcatraz 601 602 atf_check -s exit:0 -e match:"1/1 addresses added." \ 603 jexec alcatraz pfctl -t foo -T add 1.2.3.4 604 atf_check -s exit:0 -o match:" 1.2.3.4" \ 605 jexec alcatraz pfctl -t foo -T show 606 atf_check -s exit:0 -e match:"1 addresses deleted." \ 607 jexec alcatraz pfctl -t foo -T flush 608 atf_check -s exit:0 -o not-match:"1.2.3.4" \ 609 jexec alcatraz pfctl -t foo -T show 610} 611 612flush_cleanup() 613{ 614 pft_cleanup 615} 616 617atf_test_case "large" "cleanup" 618large_head() 619{ 620 atf_set descr 'Test loading a large list of addresses' 621 atf_set require.user root 622} 623 624large_body() 625{ 626 pft_init 627 pwd=$(pwd) 628 629 vnet_mkjail alcatraz 630 631 for i in `seq 1 255`; do 632 for j in `seq 1 255`; do 633 echo "1.2.${i}.${j}" >> ${pwd}/foo.lst 634 done 635 done 636 expected=$(wc -l foo.lst | awk '{ print $1; }') 637 638 jexec alcatraz pfctl -e 639 pft_set_rules alcatraz \ 640 "table <foo>" \ 641 "pass in from <foo>" \ 642 "pass" 643 644 atf_check -s exit:0 \ 645 -e match:"${expected}/${expected} addresses added." \ 646 jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst 647 actual=$(jexec alcatraz pfctl -t foo -T show | wc -l | awk '{ print $1; }') 648 if [ $actual -ne $expected ]; then 649 atf_fail "Unexpected number of table entries $expected $acual" 650 fi 651 652 # The second pass should work too, but confirm we've inserted everything 653 atf_check -s exit:0 \ 654 -e match:"0/${expected} addresses added." \ 655 jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst 656 657 echo '42.42.42.42' >> ${pwd}/foo.lst 658 expected=$((${expected} + 1)) 659 660 # And we can also insert one additional address 661 atf_check -s exit:0 \ 662 -e match:"1/${expected} addresses added." \ 663 jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst 664 665 # Try to delete one address 666 atf_check -s exit:0 \ 667 -e match:"1/1 addresses deleted." \ 668 jexec alcatraz pfctl -t foo -T delete 42.42.42.42 669 # And again, for the same address 670 atf_check -s exit:0 \ 671 -e match:"0/1 addresses deleted." \ 672 jexec alcatraz pfctl -t foo -T delete 42.42.42.42 673} 674 675large_cleanup() 676{ 677 pft_cleanup 678} 679 680atf_test_case "show_recursive" "cleanup" 681show_recursive_head() 682{ 683 atf_set descr 'Test displaying tables in every anchor' 684 atf_set require.user root 685} 686 687show_recursive_body() 688{ 689 pft_init 690 691 vnet_mkjail alcatraz 692 693 pft_set_rules alcatraz \ 694 695 (echo "table <bar> persist" 696 echo "block in quick from <bar> to any" 697 ) | jexec alcatraz pfctl -a anchorage -f - 698 699 pft_set_rules noflush alcatraz \ 700 "table <foo> counters { 192.0.2.1 }" \ 701 "pass in from <foo>" \ 702 "anchor anchorage" 703 704 jexec alcatraz pfctl -sr -a "*" 705 706 atf_check -s exit:0 -e ignore -o match:'-pa-r-- bar@anchorage' \ 707 jexec alcatraz pfctl -v -a "*" -sT 708 atf_check -s exit:0 -e ignore -o match:'--a-r-C foo' \ 709 jexec alcatraz pfctl -v -a "*" -sT 710} 711 712show_recursive_cleanup() 713{ 714 pft_cleanup 715} 716 717atf_test_case "in_anchor" "cleanup" 718in_anchor_head() 719{ 720 atf_set descr 'Test declaring tables in anchors' 721 atf_set require.user root 722} 723 724in_anchor_body() 725{ 726 pft_init 727 728 epair_send=$(vnet_mkepair) 729 ifconfig ${epair_send}a 192.0.2.1/24 up 730 731 vnet_mkjail alcatraz ${epair_send}b 732 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 733 734 jexec alcatraz pfctl -e 735 736 pft_set_rules alcatraz \ 737 "block all" \ 738 "anchor \"foo\" {\n 739 table <bar> counters { 192.0.2.1 }\n 740 pass in from <bar>\n 741 }\n" 742 743 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 744 745 jexec alcatraz pfctl -sr -a "*" -vv 746 jexec alcatraz pfctl -sT -a "*" -vv 747} 748 749in_anchor_cleanup() 750{ 751 pft_cleanup 752} 753 754atf_test_case "replace" "cleanup" 755replace_head() 756{ 757 atf_set descr 'Test table replace command' 758 atf_set require.user root 759} 760 761replace_body() 762{ 763 pft_init 764 pwd=$(pwd) 765 766 epair_send=$(vnet_mkepair) 767 ifconfig ${epair_send}a 192.0.2.1/24 up 768 769 vnet_mkjail alcatraz ${epair_send}b 770 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 771 jexec alcatraz pfctl -e 772 773 pft_set_rules alcatraz \ 774 "table <foo> counters { 192.0.2.1 }" \ 775 "block all" \ 776 "pass in from <foo> to any" \ 777 "pass out from any to <foo>" \ 778 "set skip on lo" 779 780 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 781 782 # Replace the address 783 atf_check -s exit:0 -e "match:1 addresses added." -e "match:1 addresses deleted." \ 784 jexec alcatraz pfctl -t foo -T replace 192.0.2.3 785 atf_check -s exit:0 -o "match:192.0.2.3" \ 786 jexec alcatraz pfctl -t foo -T show 787 atf_check -s exit:2 -o ignore ping -c 3 192.0.2.2 788 789 # Negated address 790 atf_check -s exit:0 -e "match:1 addresses changed." \ 791 jexec alcatraz pfctl -t foo -T replace "!192.0.2.3" 792 793 # Now add 500 addresses 794 for i in `seq 1 2`; do 795 for j in `seq 1 250`; do 796 echo "1.${i}.${j}.1" >> ${pwd}/foo.lst 797 done 798 done 799 atf_check -s exit:0 -e "match:500 addresses added." -e "match:1 addresses deleted." \ 800 jexec alcatraz pfctl -t foo -T replace -f ${pwd}/foo.lst 801 802 atf_check -s exit:0 -o "not-match:192.0.2.3" \ 803 jexec alcatraz pfctl -t foo -T show 804 805 # Loading the same list produces no changes. 806 atf_check -s exit:0 -e "match:no changes." \ 807 jexec alcatraz pfctl -t foo -T replace -f ${pwd}/foo.lst 808} 809 810replace_cleanup() 811{ 812 pft_cleanup 813} 814 815atf_test_case "load" "cleanup" 816load_head() 817{ 818 atf_set descr 'Test pfctl -T load (PR 291318)' 819 atf_set require.user root 820} 821 822load_body() 823{ 824 pft_init 825 826 epair_send=$(vnet_mkepair) 827 ifconfig ${epair_send}a 192.0.2.1/24 up 828 829 vnet_mkjail alcatraz ${epair_send}b 830 jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up 831 jexec alcatraz pfctl -e 832 833 echo -e "table <private> persist { 172.16/12 }\nblock\npass in from <private>\n" \ 834 | atf_check -s exit:0 jexec alcatraz pfctl -Tload -f - 835 836 atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 837 838 atf_check -s exit:0 -o not-match:"block" \ 839 jexec alcatraz pfctl -sr 840 atf_check -s exit:0 -o match:'172.16.0.0/12' \ 841 jexec alcatraz pfctl -Tshow -t private 842} 843 844load_cleanup() 845{ 846 pft_cleanup 847} 848 849atf_init_test_cases() 850{ 851 atf_add_test_case "v4_counters" 852 atf_add_test_case "v6_counters" 853 atf_add_test_case "match_counters" 854 atf_add_test_case "zero_one" 855 atf_add_test_case "zero_all" 856 atf_add_test_case "reset_nonzero" 857 atf_add_test_case "pr251414" 858 atf_add_test_case "automatic" 859 atf_add_test_case "network" 860 atf_add_test_case "pr259689" 861 atf_add_test_case "precreate" 862 atf_add_test_case "anchor" 863 atf_add_test_case "flush" 864 atf_add_test_case "large" 865 atf_add_test_case "show_recursive" 866 atf_add_test_case "in_anchor" 867 atf_add_test_case "replace" 868 atf_add_test_case "load" 869} 870