1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright © 2021. Rubicon Communications, LLC (Netgate). All Rights Reserved. 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 29common_dir=$(atf_get_srcdir)/../common 30 31atf_test_case "mac" "cleanup" 32mac_head() 33{ 34 atf_set descr 'Test MAC address filtering' 35 atf_set require.user root 36} 37 38mac_body() 39{ 40 pft_init 41 42 epair=$(vnet_mkepair) 43 epair_a_mac=$(ifconfig ${epair}a ether | awk '/ether/ { print $2; }') 44 45 ifconfig ${epair}a 192.0.2.1/24 up 46 47 vnet_mkjail alcatraz ${epair}b 48 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 49 50 pft_set_rules alcatraz \ 51 "ether block from ${epair_a_mac}" 52 53 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 54 55 # Now enable. Ping should fail. 56 jexec alcatraz pfctl -e 57 58 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 59 60 # Should still fail for 'to' 61 pft_set_rules alcatraz \ 62 "ether block to ${epair_a_mac}" 63 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 64 65 # Succeeds if we block a different MAC address 66 pft_set_rules alcatraz \ 67 "ether block to 00:01:02:03:04:05" 68 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 69 70 # Should still fail for 'to', even if it's in a list 71 pft_set_rules alcatraz \ 72 "ether block to { ${epair_a_mac}, 00:01:02:0:04:05 }" 73 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 74 75 # Now try this with an interface specified 76 pft_set_rules alcatraz \ 77 "ether block on ${epair}b from ${epair_a_mac}" 78 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 79 80 # Wrong interface should not match 81 pft_set_rules alcatraz \ 82 "ether block on ${epair}a from ${epair_a_mac}" 83 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 84 85 # Test negation 86 pft_set_rules alcatraz \ 87 "ether block in on ${epair}b from ! ${epair_a_mac}" 88 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 89 90 pft_set_rules alcatraz \ 91 "ether block out on ${epair}b to ! ${epair_a_mac}" 92 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 93 94 # Block everything not us 95 pft_set_rules alcatraz \ 96 "ether block out on ${epair}b to { ! ${epair_a_mac} }" 97 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 98 99 # Block us now 100 pft_set_rules alcatraz \ 101 "ether block out on ${epair}b to { ! 00:01:02:03:04:05 }" 102 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 103 104 # Block with a masked address 105 pft_set_rules alcatraz \ 106 "ether block out on ${epair}b to { ! 00:01:02:03:00:00/32 }" 107 jexec alcatraz pfctl -se 108 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 109 110 epair_prefix=$(echo $epair_a_mac | cut -c-8) 111 pft_set_rules alcatraz \ 112 "ether block out on ${epair}b to { ${epair_prefix}:00:00:00/24 }" 113 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 114 115 pft_set_rules alcatraz \ 116 "ether block out on ${epair}b to { ${epair_prefix}:00:00:00&ff:ff:ff:00:00:00 }" 117 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 118 119 # Check '-F ethernet' works 120 jexec alcatraz pfctl -F ethernet 121 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 122} 123 124mac_cleanup() 125{ 126 pft_cleanup 127} 128 129atf_test_case "proto" "cleanup" 130proto_head() 131{ 132 atf_set descr 'Test EtherType filtering' 133 atf_set require.user root 134} 135 136proto_body() 137{ 138 pft_init 139 140 epair=$(vnet_mkepair) 141 epair_a_mac=$(ifconfig ${epair}a ether | awk '/ether/ { print $2; }') 142 143 ifconfig ${epair}a 192.0.2.1/24 up 144 145 vnet_mkjail alcatraz ${epair}b 146 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 147 148 pft_set_rules alcatraz \ 149 "ether block proto 0x0810" 150 jexec alcatraz pfctl -e 151 152 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 153 154 # Block IP 155 pft_set_rules alcatraz \ 156 "ether block proto 0x0800" 157 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 158 159 # Block ARP 160 pft_set_rules alcatraz \ 161 "ether block proto 0x0806" 162 arp -d 192.0.2.2 163 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 164} 165 166proto_cleanup() 167{ 168 pft_cleanup 169} 170 171atf_test_case "direction" "cleanup" 172direction_head() 173{ 174 atf_set descr 'Test directionality of ether rules' 175 atf_set require.user root 176 atf_set require.progs jq 177} 178 179direction_body() 180{ 181 pft_init 182 183 epair=$(vnet_mkepair) 184 epair_a_mac=$(ifconfig ${epair}a ether | awk '/ether/ { print $2; }') 185 epair_b_mac=$(ifconfig ${epair}b ether | awk '/ether/ { print $2; }') 186 187 ifconfig ${epair}a 192.0.2.1/24 up 188 189 vnet_mkjail alcatraz ${epair}b 190 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 191 192 pft_set_rules alcatraz \ 193 "ether block in proto 0x0806" 194 jexec alcatraz pfctl -e 195 196 arp -d 192.0.2.2 197 jexec alcatraz arp -d 192.0.2.1 198 199 # We don't allow the jail to receive ARP requests, so if we try to ping 200 # from host to jail the host can't resolve the MAC address 201 ping -c 1 -t 1 192.0.2.2 202 203 mac=$(arp -an --libxo json \ 204 | jq '."arp"."arp-cache"[] | 205 select(."ip-address"=="192.0.2.2")."mac-address"') 206 atf_check_not_equal "$mac" "$epair_b_mac" 207 208 # Clear ARP table again 209 arp -d 192.0.2.2 210 jexec alcatraz arp -d 192.0.2.1 211 212 # However, we allow outbound ARP, so the host will learn our MAC if the 213 # jail tries to ping 214 jexec alcatraz ping -c 1 -t 1 192.0.2.1 215 216 mac=$(arp -an --libxo json \ 217 | jq '."arp"."arp-cache"[] | 218 select(."ip-address"=="192.0.2.2")."mac-address"') 219 atf_check_equal "$mac" "$epair_b_mac" 220 221 # Now do the same, but with outbound ARP blocking 222 pft_set_rules alcatraz \ 223 "ether block out proto 0x0806" 224 225 # Clear ARP table again 226 arp -d 192.0.2.2 227 jexec alcatraz arp -d 192.0.2.1 228 229 # The jail can't send ARP requests to us, so we'll never learn our MAC 230 # address 231 jexec alcatraz ping -c 1 -t 1 192.0.2.1 232 233 mac=$(jexec alcatraz arp -an --libxo json \ 234 | jq '."arp"."arp-cache"[] | 235 select(."ip-address"=="192.0.2.1")."mac-address"') 236 atf_check_not_equal "$mac" "$epair_a_mac" 237} 238 239direction_cleanup() 240{ 241 pft_cleanup 242} 243 244atf_test_case "captive" "cleanup" 245captive_head() 246{ 247 atf_set descr 'Test a basic captive portal-like setup' 248 atf_set require.user root 249} 250 251captive_body() 252{ 253 # Host is client, jail 'gw' is the captive portal gateway, jail 'srv' 254 # is a random (web)server. We use the echo protocol rather than http 255 # for the test, because that's easier. 256 pft_init 257 258 epair_gw=$(vnet_mkepair) 259 epair_srv=$(vnet_mkepair) 260 epair_gw_a_mac=$(ifconfig ${epair_gw}a ether | awk '/ether/ { print $2; }') 261 262 vnet_mkjail gw ${epair_gw}b ${epair_srv}a 263 vnet_mkjail srv ${epair_srv}b 264 265 ifconfig ${epair_gw}a 192.0.2.2/24 up 266 route add -net 198.51.100.0/24 192.0.2.1 267 jexec gw ifconfig ${epair_gw}b 192.0.2.1/24 up 268 jexec gw ifconfig lo0 127.0.0.1/8 up 269 jexec gw sysctl net.inet.ip.forwarding=1 270 271 jexec gw ifconfig ${epair_srv}a 198.51.100.1/24 up 272 jexec srv ifconfig ${epair_srv}b 198.51.100.2/24 up 273 jexec srv route add -net 192.0.2.0/24 198.51.100.1 274 275 # Sanity check 276 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.2 277 278 pft_set_rules gw \ 279 "ether pass quick proto 0x0806" \ 280 "ether pass tag captive" \ 281 "rdr on ${epair_gw}b proto tcp to port echo tagged captive -> 127.0.0.1 port echo" 282 jexec gw pfctl -e 283 284 # ICMP should still work, because we don't redirect it. 285 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.2 286 287 # Run the echo server only on the gw, so we know we've redirectly 288 # correctly if we get an echo message. 289 jexec gw /usr/sbin/inetd $(atf_get_srcdir)/echo_inetd.conf 290 291 # Confirm that we're getting redirected 292 atf_check -s exit:0 -o match:"^foo$" -x "echo foo | nc -N 198.51.100.2 7" 293 294 jexec gw killall inetd 295 296 # Now pretend we've authenticated, so add the client's MAC address 297 pft_set_rules gw \ 298 "ether pass quick proto 0x0806" \ 299 "ether pass quick from ${epair_gw_a_mac}" \ 300 "ether pass tag captive" \ 301 "rdr on ${epair_gw}b proto tcp to port echo tagged captive -> 127.0.0.1 port echo" 302 303 # No redirect, so failure. 304 atf_check -s exit:1 -x "echo foo | nc -N 198.51.100.2 7" 305 306 # Start a server in srv 307 jexec srv /usr/sbin/inetd $(atf_get_srcdir)/echo_inetd.conf 308 309 # And now we can talk to that one. 310 atf_check -s exit:0 -o match:"^foo$" -x "echo foo | nc -N 198.51.100.2 7" 311} 312 313captive_cleanup() 314{ 315 pft_cleanup 316} 317 318atf_test_case "captive_long" "cleanup" 319captive_long_head() 320{ 321 atf_set descr 'More complex captive portal setup' 322 atf_set require.user root 323} 324 325captive_long_body() 326{ 327 # Host is client, jail 'gw' is the captive portal gateway, jail 'srv' 328 # is a random (web)server. We use the echo protocol rather than http 329 # for the test, because that's easier. 330 dummynet_init 331 332 epair_gw=$(vnet_mkepair) 333 epair_srv=$(vnet_mkepair) 334 epair_gw_a_mac=$(ifconfig ${epair_gw}a ether | awk '/ether/ { print $2; }') 335 336 vnet_mkjail gw ${epair_gw}b ${epair_srv}a 337 vnet_mkjail srv ${epair_srv}b 338 339 ifconfig ${epair_gw}a 192.0.2.2/24 up 340 route add -net 198.51.100.0/24 192.0.2.1 341 jexec gw ifconfig ${epair_gw}b 192.0.2.1/24 up 342 jexec gw ifconfig lo0 127.0.0.1/8 up 343 jexec gw sysctl net.inet.ip.forwarding=1 344 345 jexec gw ifconfig ${epair_srv}a 198.51.100.1/24 up 346 jexec srv ifconfig ${epair_srv}b 198.51.100.2/24 up 347 jexec srv route add -net 192.0.2.0/24 198.51.100.1 348 349 jexec gw dnctl pipe 1 config bw 300KByte/s 350 351 # Sanity check 352 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.2 353 354 pft_set_rules gw \ 355 "ether anchor \"captiveportal\" on { ${epair_gw}b } {" \ 356 "ether pass quick proto { 0x0806, 0x8035, 0x888e, 0x88c7, 0x8863, 0x8864 }" \ 357 "ether pass tag \"captive\"" \ 358 "}" \ 359 "rdr on ${epair_gw}b proto tcp to port daytime tagged captive -> 127.0.0.1 port echo" 360 jexec gw pfctl -e 361 362 # ICMP should still work, because we don't redirect it. 363 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.2 364 365 jexec gw /usr/sbin/inetd -p gw.pid $(atf_get_srcdir)/echo_inetd.conf 366 jexec srv /usr/sbin/inetd -p srv.pid $(atf_get_srcdir)/daytime_inetd.conf 367 368 echo foo | nc -N 198.51.100.2 13 369 370 # Confirm that we're getting redirected 371 atf_check -s exit:0 -o match:"^foo$" -x "echo foo | nc -N 198.51.100.2 13" 372 373 # Now update the rules to allow our client to pass without redirect 374 pft_set_rules gw \ 375 "ether anchor \"captiveportal\" on { ${epair_gw}b } {" \ 376 "ether pass quick proto { 0x0806, 0x8035, 0x888e, 0x88c7, 0x8863, 0x8864 }" \ 377 "ether pass quick from { ${epair_gw_a_mac} } dnpipe 1" \ 378 "ether pass tag \"captive\"" \ 379 "}" \ 380 "rdr on ${epair_gw}b proto tcp to port daytime tagged captive -> 127.0.0.1 port echo" 381 382 # We're not being redirected and get datime information now 383 atf_check -s exit:0 -o match:"^(Mon|Tue|Wed|Thu|Fri|Sat|Sun)" -x "echo foo | nc -N 198.51.100.2 13" 384 385 jexec gw killall inetd 386 jexec srv killall inetd 387} 388 389captive_long_cleanup() 390{ 391 pft_cleanup 392} 393 394atf_test_case "dummynet" "cleanup" 395dummynet_head() 396{ 397 atf_set descr 'Test dummynet for L2 traffic' 398 atf_set require.user root 399} 400 401dummynet_body() 402{ 403 pft_init 404 405 if ! kldstat -q -m dummynet; then 406 atf_skip "This test requires dummynet" 407 fi 408 409 epair=$(vnet_mkepair) 410 vnet_mkjail alcatraz ${epair}b 411 412 ifconfig ${epair}a 192.0.2.1/24 up 413 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 414 415 # Sanity check 416 atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 417 418 jexec alcatraz dnctl pipe 1 config bw 30Byte/s 419 jexec alcatraz pfctl -e 420 pft_set_rules alcatraz \ 421 "ether pass in dnpipe 1" 422 423 # Ensure things don't break if non-IP(v4/v6) traffic hits dummynet 424 arp -d 192.0.2.2 425 426 # single ping succeeds just fine 427 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 428 429 # Saturate the link 430 ping -i .1 -c 5 -s 1200 192.0.2.2 431 432 # We should now be hitting the limits and get this packet dropped. 433 atf_check -s exit:2 -o ignore ping -c 1 -s 1200 192.0.2.2 434 435 # We can now also dummynet outbound traffic! 436 pft_set_rules alcatraz \ 437 "ether pass out dnpipe 1" 438 439 # We should still be hitting the limits and get this packet dropped. 440 atf_check -s exit:2 -o ignore ping -c 1 -s 1200 192.0.2.2 441} 442 443dummynet_cleanup() 444{ 445 pft_cleanup 446} 447 448atf_test_case "anchor" "cleanup" 449anchor_head() 450{ 451 atf_set descr 'Test ether anchors' 452 atf_set require.user root 453} 454 455anchor_body() 456{ 457 pft_init 458 459 epair=$(vnet_mkepair) 460 epair_a_mac=$(ifconfig ${epair}a ether | awk '/ether/ { print $2; }') 461 462 vnet_mkjail alcatraz ${epair}b 463 464 ifconfig ${epair}a 192.0.2.1/24 up 465 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 466 467 # Sanity check 468 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 469 470 jexec alcatraz pfctl -e 471 pft_set_rules alcatraz \ 472 "ether anchor \"foo\" in on lo0 {" \ 473 "ether block" \ 474 "}" 475 476 # That only filters on lo0, so we should still be able to pass traffic 477 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 478 479 pft_set_rules alcatraz \ 480 "ether block in" \ 481 "ether anchor \"foo\" in on ${epair}b {" \ 482 "ether pass" \ 483 "}" 484 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 485 486 pft_set_rules alcatraz \ 487 "ether pass" \ 488 "ether anchor \"bar\" in on ${epair}b {" \ 489 "ether block" \ 490 "}" 491 atf_check -s exit:2 -o ignore ping -c 1 -t 2 192.0.2.2 492 493 pft_set_rules alcatraz \ 494 "ether block in" \ 495 "ether anchor \"baz\" on ${epair}b {" \ 496 "ether pass in from 01:02:03:04:05:06" \ 497 "}" \ 498 "ether pass in from ${epair_a_mac}" 499 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 500 501 atf_check -s exit:0 -o match:'baz' jexec alcatraz pfctl -sA 502} 503 504anchor_cleanup() 505{ 506 pft_cleanup 507} 508 509atf_test_case "ip" "cleanup" 510ip_head() 511{ 512 atf_set descr 'Test filtering based on IP source/destination' 513 atf_set require.user root 514} 515 516ip_body() 517{ 518 pft_init 519 520 epair=$(vnet_mkepair) 521 522 vnet_mkjail alcatraz ${epair}b 523 524 ifconfig ${epair}a 192.0.2.1/24 up 525 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 526 527 # Sanity check 528 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 529 530 jexec alcatraz pfctl -e 531 pft_set_rules alcatraz \ 532 "ether pass" \ 533 "ether block in l3 from 192.0.2.1" 534 535 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 536 537 # Change IP address and we can ping again 538 ifconfig ${epair}a 192.0.2.3/24 up 539 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 540 541 # Test the 'to' keyword too 542 pft_set_rules alcatraz \ 543 "ether pass" \ 544 "ether block out l3 to 192.0.2.3" 545 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 546 547 # Test table 548 pft_set_rules alcatraz \ 549 "table <tbl> { 192.0.2.3 }" \ 550 "ether pass" \ 551 "ether block out l3 to <tbl>" 552 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 553} 554 555ip_cleanup() 556{ 557 pft_cleanup 558} 559 560atf_test_case "tag" "cleanup" 561tag_head() 562{ 563 atf_set descr 'Test setting tags' 564 atf_set require.user root 565} 566 567tag_body() 568{ 569 pft_init 570 571 epair=$(vnet_mkepair) 572 573 vnet_mkjail alcatraz ${epair}b 574 ifconfig ${epair}a 192.0.2.1/24 up 575 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 576 577 # Sanity check 578 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 579 580 jexec alcatraz pfctl -e 581 pft_set_rules alcatraz \ 582 "ether pass in tag foo" \ 583 "block in tagged foo" 584 585 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 586 587 pft_set_rules alcatraz \ 588 "ether pass in tag bar" \ 589 "block in tagged foo" 590 591 # Still passes when tagged differently 592 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 593} 594 595tag_cleanup() 596{ 597 pft_cleanup 598} 599 600atf_test_case "match_tag" "cleanup" 601match_tag_head() 602{ 603 atf_set descr 'Test matching tags' 604 atf_set require.user root 605} 606 607match_tag_body() 608{ 609 pft_init 610 611 epair=$(vnet_mkepair) 612 613 vnet_mkjail alcatraz ${epair}b 614 615 ifconfig ${epair}a 192.0.2.1/24 up 616 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 617 618 # Sanity check 619 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 620 621 jexec alcatraz pfctl -e 622 pft_set_rules alcatraz \ 623 "ether block out tagged foo" \ 624 "pass in proto icmp tag foo" 625 626 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 627 628 pft_set_rules alcatraz \ 629 "ether block out tagged bar" \ 630 "pass in proto icmp tag foo" 631 632 # Still passes when tagged differently 633 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 634} 635 636match_tag_cleanup() 637{ 638 pft_cleanup 639} 640 641atf_test_case "short_pkt" "cleanup" 642short_pkt_head() 643{ 644 atf_set descr 'Test overly short Ethernet packets' 645 atf_set require.user root 646 atf_set require.progs scapy 647} 648 649short_pkt_body() 650{ 651 pft_init 652 653 epair=$(vnet_mkepair) 654 ifconfig ${epair}a 192.0.2.1/24 up 655 656 vnet_mkjail alcatraz ${epair}b 657 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 658 659 jexec alcatraz pfctl -e 660 pft_set_rules alcatraz \ 661 "ether pass in" \ 662 "ether pass out" \ 663 "ether pass in l3 from 192.0.2.1" 664 665 # Sanity check 666 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 667 668 jexec alcatraz pfctl -se -v 669 670 # Try sending ever shorter ping requests 671 # BPF won't let us send anything shorter than an Ethernet header, but 672 # that's good enough for this test 673 $(atf_get_srcdir)/pft_ether.py \ 674 --sendif ${epair}a \ 675 --to 192.0.2.2 \ 676 --len 14-64 677} 678 679short_pkt_cleanup() 680{ 681 pft_cleanup 682} 683 684atf_test_case "bridge_to" "cleanup" 685bridge_to_head() 686{ 687 atf_set descr 'Test bridge-to keyword' 688 atf_set require.user root 689 atf_set require.progs scapy 690} 691 692bridge_to_body() 693{ 694 pft_init 695 696 epair_in=$(vnet_mkepair) 697 epair_out=$(vnet_mkepair) 698 699 ifconfig ${epair_in}a 192.0.2.1/24 up 700 ifconfig ${epair_out}a up 701 702 vnet_mkjail alcatraz ${epair_in}b ${epair_out}b 703 jexec alcatraz ifconfig ${epair_in}b 192.0.2.2/24 up 704 jexec alcatraz ifconfig ${epair_out}b up 705 706 # Sanity check 707 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 708 atf_check -s exit:1 -o ignore \ 709 ${common_dir}/pft_ping.py \ 710 --sendif ${epair_in}a \ 711 --to 192.0.2.2 \ 712 --recvif ${epair_out}a 713 714 jexec alcatraz pfctl -e 715 pft_set_rules alcatraz \ 716 "ether pass in on ${epair_in}b bridge-to ${epair_out}b" 717 718 # Now the packets go out epair_out rather than be processed locally 719 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.2 720 atf_check -s exit:0 -o ignore \ 721 ${common_dir}/pft_ping.py \ 722 --sendif ${epair_in}a \ 723 --to 192.0.2.2 \ 724 --recvif ${epair_out}a 725} 726 727bridge_to_cleanup() 728{ 729 pft_cleanup 730} 731 732atf_init_test_cases() 733{ 734 atf_add_test_case "mac" 735 atf_add_test_case "proto" 736 atf_add_test_case "direction" 737 atf_add_test_case "captive" 738 atf_add_test_case "captive_long" 739 atf_add_test_case "dummynet" 740 atf_add_test_case "anchor" 741 atf_add_test_case "ip" 742 atf_add_test_case "tag" 743 atf_add_test_case "match_tag" 744 atf_add_test_case "short_pkt" 745 atf_add_test_case "bridge_to" 746} 747