1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2018 Orange Business Services 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 "basic" "cleanup" 32basic_head() 33{ 34 atf_set descr 'Basic pfsync test' 35 atf_set require.user root 36} 37 38basic_body() 39{ 40 common_body 41} 42 43common_body() 44{ 45 defer=$1 46 pfsynct_init 47 48 epair_sync=$(vnet_mkepair) 49 epair_one=$(vnet_mkepair) 50 epair_two=$(vnet_mkepair) 51 52 vnet_mkjail one ${epair_one}a ${epair_sync}a 53 vnet_mkjail two ${epair_two}a ${epair_sync}b 54 55 # pfsync interface 56 jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up 57 jexec one ifconfig ${epair_one}a 198.51.100.1/24 up 58 jexec one ifconfig pfsync0 \ 59 syncdev ${epair_sync}a \ 60 maxupd 1 \ 61 $defer \ 62 up 63 jexec two ifconfig ${epair_two}a 198.51.100.2/24 up 64 jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up 65 jexec two ifconfig pfsync0 \ 66 syncdev ${epair_sync}b \ 67 maxupd 1 \ 68 $defer \ 69 up 70 71 # Enable pf! 72 jexec one pfctl -e 73 pft_set_rules one \ 74 "set skip on ${epair_sync}a" \ 75 "pass out keep state" 76 jexec two pfctl -e 77 pft_set_rules two \ 78 "set skip on ${epair_sync}b" \ 79 "pass out keep state" 80 81 hostid_one=$(jexec one pfctl -si -v | awk '/Hostid:/ { gsub(/0x/, "", $2); printf($2); }') 82 83 ifconfig ${epair_one}b 198.51.100.254/24 up 84 85 ping -c 1 -S 198.51.100.254 198.51.100.1 86 87 # Give pfsync time to do its thing 88 sleep 2 89 90 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 91 grep 198.51.100.254 ; then 92 atf_fail "state not found on synced host" 93 fi 94 95 if ! jexec two pfctl -sc | grep ""${hostid_one}""; 96 then 97 jexec two pfctl -sc 98 atf_fail "HostID for host one not found on two" 99 fi 100} 101 102basic_cleanup() 103{ 104 pfsynct_cleanup 105} 106 107atf_test_case "basic_defer" "cleanup" 108basic_defer_head() 109{ 110 atf_set descr 'Basic defer mode pfsync test' 111 atf_set require.user root 112} 113 114basic_defer_body() 115{ 116 common_body defer 117} 118 119basic_defer_cleanup() 120{ 121 pfsynct_cleanup 122} 123 124atf_test_case "defer" "cleanup" 125defer_head() 126{ 127 atf_set descr 'Defer mode pfsync test' 128 atf_set require.user root 129 atf_set require.progs scapy 130} 131 132defer_body() 133{ 134 pfsynct_init 135 136 epair_sync=$(vnet_mkepair) 137 epair_in=$(vnet_mkepair) 138 epair_out=$(vnet_mkepair) 139 140 vnet_mkjail alcatraz ${epair_sync}a ${epair_in}a ${epair_out}a 141 142 jexec alcatraz ifconfig ${epair_sync}a 192.0.2.1/24 up 143 jexec alcatraz ifconfig ${epair_out}a 198.51.100.1/24 up 144 jexec alcatraz ifconfig ${epair_in}a 203.0.113.1/24 up 145 jexec alcatraz arp -s 203.0.113.2 00:01:02:03:04:05 146 jexec alcatraz sysctl net.inet.ip.forwarding=1 147 148 # Set a long defer delay 149 jexec alcatraz sysctl net.pfsync.defer_delay=2500 150 151 jexec alcatraz ifconfig pfsync0 \ 152 syncdev ${epair_sync}a \ 153 maxupd 1 \ 154 defer \ 155 up 156 157 ifconfig ${epair_sync}b 192.0.2.2/24 up 158 ifconfig ${epair_out}b 198.51.100.2/24 up 159 ifconfig ${epair_in}b up 160 route add -net 203.0.113.0/24 198.51.100.1 161 162 # Enable pf 163 jexec alcatraz sysctl net.pf.filter_local=0 164 jexec alcatraz pfctl -e 165 pft_set_rules alcatraz \ 166 "set skip on ${epair_sync}a" \ 167 "pass keep state" 168 169 atf_check -s exit:0 env PYTHONPATH=${common_dir} \ 170 $(atf_get_srcdir)/pfsync_defer.py \ 171 --syncdev ${epair_sync}b \ 172 --indev ${epair_in}b \ 173 --outdev ${epair_out}b 174 175 # Now disable defer mode and expect failure. 176 jexec alcatraz ifconfig pfsync0 -defer 177 178 # Flush state 179 pft_set_rules alcatraz \ 180 "set skip on ${epair_sync}a" \ 181 "pass keep state" 182 183 atf_check -s exit:3 env PYTHONPATH=${common_dir} \ 184 $(atf_get_srcdir)/pfsync_defer.py \ 185 --syncdev ${epair_sync}b \ 186 --indev ${epair_in}b \ 187 --outdev ${epair_out}b 188} 189 190defer_cleanup() 191{ 192 pfsynct_cleanup 193} 194 195atf_test_case "bulk" "cleanup" 196bulk_head() 197{ 198 atf_set descr 'Test bulk updates' 199 atf_set require.user root 200} 201 202bulk_body() 203{ 204 pfsynct_init 205 206 epair_sync=$(vnet_mkepair) 207 epair_one=$(vnet_mkepair) 208 epair_two=$(vnet_mkepair) 209 210 vnet_mkjail one ${epair_one}a ${epair_sync}a 211 vnet_mkjail two ${epair_two}a ${epair_sync}b 212 213 # pfsync interface 214 jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up 215 jexec one ifconfig ${epair_one}a 198.51.100.1/24 up 216 jexec one ifconfig pfsync0 \ 217 syncdev ${epair_sync}a \ 218 maxupd 1\ 219 up 220 jexec two ifconfig ${epair_two}a 198.51.100.2/24 up 221 jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up 222 223 # Enable pf 224 jexec one pfctl -e 225 pft_set_rules one \ 226 "set skip on ${epair_sync}a" \ 227 "pass keep state" 228 jexec two pfctl -e 229 pft_set_rules two \ 230 "set skip on ${epair_sync}b" \ 231 "pass keep state" 232 233 ifconfig ${epair_one}b 198.51.100.254/24 up 234 235 # Create state prior to setting up pfsync 236 ping -c 1 -S 198.51.100.254 198.51.100.1 237 238 # Wait before setting up pfsync on two, so we don't accidentally catch 239 # the update anyway. 240 sleep 1 241 242 # Now set up pfsync in jail two 243 jexec two ifconfig pfsync0 \ 244 syncdev ${epair_sync}b \ 245 up 246 247 # Give pfsync time to do its thing 248 sleep 2 249 250 jexec two pfctl -s states 251 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 252 grep 198.51.100.2 ; then 253 atf_fail "state not found on synced host" 254 fi 255} 256 257bulk_cleanup() 258{ 259 pfsynct_cleanup 260} 261 262atf_test_case "pbr" "cleanup" 263pbr_head() 264{ 265 atf_set descr 'route_to and reply_to directives test' 266 atf_set require.user root 267 atf_set timeout '600' 268} 269 270pbr_body() 271{ 272 pbr_common_body 273} 274 275pbr_cleanup() 276{ 277 pbr_common_cleanup 278} 279 280atf_test_case "pfsync_pbr" "cleanup" 281pfsync_pbr_head() 282{ 283 atf_set descr 'route_to and reply_to directives pfsync test' 284 atf_set require.user root 285 atf_set timeout '600' 286} 287 288pfsync_pbr_body() 289{ 290 pbr_common_body backup_promotion 291} 292 293pfsync_pbr_cleanup() 294{ 295 pbr_common_cleanup 296} 297 298pbr_common_body() 299{ 300 # + builds bellow topology and initiate a single ping session 301 # from client to server. 302 # + gw* forward traffic through pbr not fib lookups. 303 # + if backup_promotion arg is given, a carp failover event occurs 304 # during the ping session on both gateways. 305 # ┌──────┐ 306 # │client│ 307 # └───┬──┘ 308 # │ 309 # ┌───┴───┐ 310 # │bridge0│ 311 # └┬─────┬┘ 312 # │ │ 313 # ┌────────────────┴─┐ ┌─┴────────────────┐ 314 # │gw_route_to_master├─┤gw_route_to_backup│ 315 # └────────────────┬─┘ └─┬────────────────┘ 316 # │ │ 317 # ┌┴─────┴┐ 318 # │bridge1│ 319 # └┬─────┬┘ 320 # │ │ 321 # ┌────────────────┴─┐ ┌─┴────────────────┐ 322 # │gw_reply_to_master├─┤gw_reply_to_backup│ 323 # └────────────────┬─┘ └─┬────────────────┘ 324 # │ │ 325 # ┌┴─────┴┐ 326 # │bridge2│ 327 # └───┬───┘ 328 # │ 329 # ┌───┴──┐ 330 # │server│ 331 # └──────┘ 332 333 if ! kldstat -q -m carp 334 then 335 atf_skip "This test requires carp" 336 fi 337 pfsynct_init 338 vnet_init_bridge 339 340 bridge0=$(vnet_mkbridge) 341 bridge1=$(vnet_mkbridge) 342 bridge2=$(vnet_mkbridge) 343 344 epair_sync_gw_route_to=$(vnet_mkepair) 345 epair_sync_gw_reply_to=$(vnet_mkepair) 346 epair_client_bridge0=$(vnet_mkepair) 347 348 epair_gw_route_to_master_bridge0=$(vnet_mkepair) 349 epair_gw_route_to_backup_bridge0=$(vnet_mkepair) 350 epair_gw_route_to_master_bridge1=$(vnet_mkepair) 351 epair_gw_route_to_backup_bridge1=$(vnet_mkepair) 352 353 epair_gw_reply_to_master_bridge1=$(vnet_mkepair) 354 epair_gw_reply_to_backup_bridge1=$(vnet_mkepair) 355 epair_gw_reply_to_master_bridge2=$(vnet_mkepair) 356 epair_gw_reply_to_backup_bridge2=$(vnet_mkepair) 357 358 epair_server_bridge2=$(vnet_mkepair) 359 360 ifconfig ${bridge0} up 361 ifconfig ${epair_client_bridge0}b up 362 ifconfig ${epair_gw_route_to_master_bridge0}b up 363 ifconfig ${epair_gw_route_to_backup_bridge0}b up 364 ifconfig ${bridge0} \ 365 addm ${epair_client_bridge0}b \ 366 addm ${epair_gw_route_to_master_bridge0}b \ 367 addm ${epair_gw_route_to_backup_bridge0}b 368 369 ifconfig ${bridge1} up 370 ifconfig ${epair_gw_route_to_master_bridge1}b up 371 ifconfig ${epair_gw_route_to_backup_bridge1}b up 372 ifconfig ${epair_gw_reply_to_master_bridge1}b up 373 ifconfig ${epair_gw_reply_to_backup_bridge1}b up 374 ifconfig ${bridge1} \ 375 addm ${epair_gw_route_to_master_bridge1}b \ 376 addm ${epair_gw_route_to_backup_bridge1}b \ 377 addm ${epair_gw_reply_to_master_bridge1}b \ 378 addm ${epair_gw_reply_to_backup_bridge1}b 379 380 ifconfig ${bridge2} up 381 ifconfig ${epair_gw_reply_to_master_bridge2}b up 382 ifconfig ${epair_gw_reply_to_backup_bridge2}b up 383 ifconfig ${epair_server_bridge2}b up 384 ifconfig ${bridge2} \ 385 addm ${epair_gw_reply_to_master_bridge2}b \ 386 addm ${epair_gw_reply_to_backup_bridge2}b \ 387 addm ${epair_server_bridge2}b 388 389 vnet_mkjail client ${epair_client_bridge0}a 390 jexec client hostname client 391 vnet_mkjail gw_route_to_master \ 392 ${epair_gw_route_to_master_bridge0}a \ 393 ${epair_gw_route_to_master_bridge1}a \ 394 ${epair_sync_gw_route_to}a 395 jexec gw_route_to_master hostname gw_route_to_master 396 vnet_mkjail gw_route_to_backup \ 397 ${epair_gw_route_to_backup_bridge0}a \ 398 ${epair_gw_route_to_backup_bridge1}a \ 399 ${epair_sync_gw_route_to}b 400 jexec gw_route_to_backup hostname gw_route_to_backup 401 vnet_mkjail gw_reply_to_master \ 402 ${epair_gw_reply_to_master_bridge1}a \ 403 ${epair_gw_reply_to_master_bridge2}a \ 404 ${epair_sync_gw_reply_to}a 405 jexec gw_reply_to_master hostname gw_reply_to_master 406 vnet_mkjail gw_reply_to_backup \ 407 ${epair_gw_reply_to_backup_bridge1}a \ 408 ${epair_gw_reply_to_backup_bridge2}a \ 409 ${epair_sync_gw_reply_to}b 410 jexec gw_reply_to_backup hostname gw_reply_to_backup 411 vnet_mkjail server ${epair_server_bridge2}a 412 jexec server hostname server 413 414 jexec client ifconfig ${epair_client_bridge0}a inet 198.18.0.1/24 up 415 jexec client route add 198.18.2.0/24 198.18.0.10 416 417 jexec gw_route_to_master ifconfig ${epair_sync_gw_route_to}a \ 418 inet 198.19.10.1/24 up 419 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ 420 inet 198.18.0.8/24 up 421 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ 422 alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 50 423 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ 424 inet 198.18.1.8/24 up 425 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ 426 alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 50 427 jexec gw_route_to_master sysctl net.inet.ip.forwarding=1 428 jexec gw_route_to_master sysctl net.inet.carp.preempt=1 429 430 vnet_ifrename_jail gw_route_to_master ${epair_sync_gw_route_to}a if_pfsync 431 vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge0}a if_br0 432 vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge1}a if_br1 433 434 jexec gw_route_to_master ifconfig pfsync0 \ 435 syncpeer 198.19.10.2 \ 436 syncdev if_pfsync \ 437 maxupd 1 \ 438 up 439 pft_set_rules gw_route_to_master \ 440 "keep_state = 'tag auth_packet keep state'" \ 441 "set timeout { icmp.first 120, icmp.error 60 }" \ 442 "block log all" \ 443 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 444 "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ 445 "block drop in quick to 224.0.0.18/32" \ 446 "pass out quick tagged auth_packet keep state" \ 447 "pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state" 448 jexec gw_route_to_master pfctl -e 449 450 jexec gw_route_to_backup ifconfig ${epair_sync_gw_route_to}b \ 451 inet 198.19.10.2/24 up 452 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ 453 inet 198.18.0.9/24 up 454 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ 455 alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 100 456 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ 457 inet 198.18.1.9/24 up 458 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ 459 alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 100 460 jexec gw_route_to_backup sysctl net.inet.ip.forwarding=1 461 jexec gw_route_to_backup sysctl net.inet.carp.preempt=1 462 463 vnet_ifrename_jail gw_route_to_backup ${epair_sync_gw_route_to}b if_pfsync 464 vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge0}a if_br0 465 vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge1}a if_br1 466 467 jexec gw_route_to_backup ifconfig pfsync0 \ 468 syncpeer 198.19.10.1 \ 469 syncdev if_pfsync \ 470 up 471 pft_set_rules gw_route_to_backup \ 472 "keep_state = 'tag auth_packet keep state'" \ 473 "set timeout { icmp.first 120, icmp.error 60 }" \ 474 "block log all" \ 475 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 476 "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ 477 "block drop in quick to 224.0.0.18/32" \ 478 "pass out quick tagged auth_packet keep state" \ 479 "pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state" 480 jexec gw_route_to_backup pfctl -e 481 482 jexec gw_reply_to_master ifconfig ${epair_sync_gw_reply_to}a \ 483 inet 198.19.20.1/24 up 484 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ 485 inet 198.18.1.18/24 up 486 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ 487 alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 50 488 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ 489 inet 198.18.2.18/24 up 490 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ 491 alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 50 492 jexec gw_reply_to_master sysctl net.inet.ip.forwarding=1 493 jexec gw_reply_to_master sysctl net.inet.carp.preempt=1 494 495 vnet_ifrename_jail gw_reply_to_master ${epair_sync_gw_reply_to}a if_pfsync 496 vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge1}a if_br1 497 vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge2}a if_br2 498 499 jexec gw_reply_to_master ifconfig pfsync0 \ 500 syncpeer 198.19.20.2 \ 501 syncdev if_pfsync \ 502 maxupd 1 \ 503 up 504 pft_set_rules gw_reply_to_master \ 505 "set timeout { icmp.first 120, icmp.error 60 }" \ 506 "block log all" \ 507 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 508 "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ 509 "block drop in quick to 224.0.0.18/32" \ 510 "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ 511 "pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state" 512 jexec gw_reply_to_master pfctl -e 513 514 jexec gw_reply_to_backup ifconfig ${epair_sync_gw_reply_to}b \ 515 inet 198.19.20.2/24 up 516 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ 517 inet 198.18.1.19/24 up 518 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ 519 alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 100 520 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ 521 inet 198.18.2.19/24 up 522 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ 523 alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 100 524 jexec gw_reply_to_backup sysctl net.inet.ip.forwarding=1 525 jexec gw_reply_to_backup sysctl net.inet.carp.preempt=1 526 527 vnet_ifrename_jail gw_reply_to_backup ${epair_sync_gw_reply_to}b if_pfsync 528 vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge1}a if_br1 529 vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge2}a if_br2 530 531 jexec gw_reply_to_backup ifconfig pfsync0 \ 532 syncpeer 198.19.20.1 \ 533 syncdev if_pfsync \ 534 up 535 pft_set_rules gw_reply_to_backup \ 536 "set timeout { icmp.first 120, icmp.error 60 }" \ 537 "block log all" \ 538 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 539 "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ 540 "block drop in quick to 224.0.0.18/32" \ 541 "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ 542 "pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state" 543 jexec gw_reply_to_backup pfctl -e 544 545 jexec server ifconfig ${epair_server_bridge2}a inet 198.18.2.1/24 up 546 jexec server route add 198.18.0.0/24 198.18.2.20 547 548 # Waiting for platform to settle 549 while ! jexec gw_route_to_backup ifconfig | grep 'carp: BACKUP' 550 do 551 sleep 1 552 done 553 while ! jexec gw_reply_to_backup ifconfig | grep 'carp: BACKUP' 554 do 555 sleep 1 556 done 557 while ! jexec client ping -c 10 198.18.2.1 | grep ', 0.0% packet loss' 558 do 559 sleep 1 560 done 561 562 # Checking cluster members pf.conf checksums match 563 gw_route_to_master_checksum=$(jexec gw_route_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 564 gw_route_to_backup_checksum=$(jexec gw_route_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 565 gw_reply_to_master_checksum=$(jexec gw_reply_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 566 gw_reply_to_backup_checksum=$(jexec gw_reply_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 567 if [ "$gw_route_to_master_checksum" != "$gw_route_to_backup_checksum" ] 568 then 569 atf_fail "gw_route_to cluster members pf.conf do not match each others" 570 fi 571 if [ "$gw_reply_to_master_checksum" != "$gw_reply_to_backup_checksum" ] 572 then 573 atf_fail "gw_reply_to cluster members pf.conf do not match each others" 574 fi 575 576 # Creating state entries 577 (jexec client ping -c 10 198.18.2.1 >ping.stdout) & 578 579 if [ "$1" = "backup_promotion" ] 580 then 581 sleep 1 582 jexec gw_route_to_backup ifconfig if_br0 vhid 10 advskew 0 583 jexec gw_route_to_backup ifconfig if_br1 vhid 11 advskew 0 584 jexec gw_reply_to_backup ifconfig if_br1 vhid 21 advskew 0 585 jexec gw_reply_to_backup ifconfig if_br2 vhid 22 advskew 0 586 fi 587 while ! grep -q -e 'packet loss' ping.stdout 588 do 589 sleep 1 590 done 591 592 atf_check -s exit:0 -e ignore -o ignore grep ', 0.0% packet loss' ping.stdout 593} 594 595pbr_common_cleanup() 596{ 597 pft_cleanup 598} 599 600atf_test_case "ipsec" "cleanup" 601ipsec_head() 602{ 603 atf_set descr 'Transport pfsync over IPSec' 604 atf_set require.user root 605} 606 607ipsec_body() 608{ 609 if ! sysctl -q kern.features.ipsec >/dev/null ; then 610 atf_skip "This test requires ipsec" 611 fi 612 613 # Run the common test, to set up pfsync 614 common_body 615 616 # But we want unicast pfsync 617 jexec one ifconfig pfsync0 syncpeer 192.0.2.2 618 jexec two ifconfig pfsync0 syncpeer 192.0.2.1 619 620 # Flush existing states 621 jexec one pfctl -Fs 622 jexec two pfctl -Fs 623 624 # Now define an ipsec policy to run over the epair_sync interfaces 625 echo "flush; 626 spdflush; 627 spdadd 192.0.2.1/32 192.0.2.2/32 any -P out ipsec esp/transport//require; 628 spdadd 192.0.2.2/32 192.0.2.1/32 any -P in ipsec esp/transport//require; 629 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; 630 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ 631 | jexec one setkey -c 632 633 echo "flush; 634 spdflush; 635 spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; 636 spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; 637 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567891\"; 638 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567891\";" \ 639 | jexec two setkey -c 640 641 # We've set incompatible keys, so pfsync will be broken. 642 ping -c 1 -S 198.51.100.254 198.51.100.1 643 644 # Give pfsync time to do its thing 645 sleep 2 646 647 if jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 648 grep 198.51.100.2 ; then 649 atf_fail "state synced although IPSec should have prevented it" 650 fi 651 652 # Flush existing states 653 jexec one pfctl -Fs 654 jexec two pfctl -Fs 655 656 # Fix the IPSec key to match 657 echo "flush; 658 spdflush; 659 spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; 660 spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; 661 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; 662 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ 663 | jexec two setkey -c 664 665 ping -c 1 -S 198.51.100.254 198.51.100.1 666 667 # Give pfsync time to do its thing 668 sleep 2 669 670 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 671 grep 198.51.100.2 ; then 672 atf_fail "state not found on synced host" 673 fi 674} 675 676ipsec_cleanup() 677{ 678 pft_cleanup 679} 680 681atf_test_case "timeout" "cleanup" 682timeout_head() 683{ 684 atf_set descr 'Trigger pfsync_timeout()' 685 atf_set require.user root 686} 687 688timeout_body() 689{ 690 pft_init 691 692 vnet_mkjail one 693 694 jexec one ifconfig lo0 127.0.0.1/8 up 695 jexec one ifconfig lo0 inet6 ::1/128 up 696 697 pft_set_rules one \ 698 "pass all" 699 jexec one pfctl -e 700 jexec one ifconfig pfsync0 defer up 701 702 jexec one ping -c 1 ::1 703 jexec one ping -c 1 127.0.0.1 704 705 # Give pfsync_timeout() time to fire (a callout on a 1 second delay) 706 sleep 2 707} 708 709timeout_cleanup() 710{ 711 pft_cleanup 712} 713 714atf_test_case "basic_ipv6_unicast" "cleanup" 715basic_ipv6_unicast_head() 716{ 717 atf_set descr 'Basic pfsync test (IPv6)' 718 atf_set require.user root 719} 720 721basic_ipv6_unicast_body() 722{ 723 pfsynct_init 724 725 epair_sync=$(vnet_mkepair) 726 epair_one=$(vnet_mkepair) 727 epair_two=$(vnet_mkepair) 728 729 vnet_mkjail one ${epair_one}a ${epair_sync}a 730 vnet_mkjail two ${epair_two}a ${epair_sync}b 731 732 # pfsync interface 733 jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up 734 jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up 735 jexec one ifconfig pfsync0 \ 736 syncdev ${epair_sync}a \ 737 syncpeer fd2c::2 \ 738 maxupd 1 \ 739 up 740 jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up 741 jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up 742 jexec two ifconfig pfsync0 \ 743 syncdev ${epair_sync}b \ 744 syncpeer fd2c::1 \ 745 maxupd 1 \ 746 up 747 748 # Enable pf! 749 jexec one pfctl -e 750 pft_set_rules one \ 751 "block on ${epair_sync}a inet" \ 752 "pass out keep state" 753 jexec two pfctl -e 754 pft_set_rules two \ 755 "block on ${epair_sync}b inet" \ 756 "pass out keep state" 757 758 ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up 759 760 ping6 -c 1 -S fd2b::f0 fd2b::1 761 762 # Give pfsync time to do its thing 763 sleep 2 764 765 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ 766 grep fd2b::f0 ; then 767 atf_fail "state not found on synced host" 768 fi 769} 770 771basic_ipv6_unicast_cleanup() 772{ 773 pfsynct_cleanup 774} 775 776atf_test_case "basic_ipv6" "cleanup" 777basic_ipv6_head() 778{ 779 atf_set descr 'Basic pfsync test (IPv6)' 780 atf_set require.user root 781} 782 783basic_ipv6_body() 784{ 785 pfsynct_init 786 787 epair_sync=$(vnet_mkepair) 788 epair_one=$(vnet_mkepair) 789 epair_two=$(vnet_mkepair) 790 791 vnet_mkjail one ${epair_one}a ${epair_sync}a 792 vnet_mkjail two ${epair_two}a ${epair_sync}b 793 794 # pfsync interface 795 jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up 796 jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up 797 jexec one ifconfig pfsync0 \ 798 syncdev ${epair_sync}a \ 799 syncpeer ff12::f0 \ 800 maxupd 1 \ 801 up 802 jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up 803 jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up 804 jexec two ifconfig pfsync0 \ 805 syncdev ${epair_sync}b \ 806 syncpeer ff12::f0 \ 807 maxupd 1 \ 808 up 809 810 # Enable pf! 811 jexec one pfctl -e 812 pft_set_rules one \ 813 "block on ${epair_sync}a inet" \ 814 "pass out keep state" 815 jexec two pfctl -e 816 pft_set_rules two \ 817 "block on ${epair_sync}b inet" \ 818 "pass out keep state" 819 820 ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up 821 822 ping6 -c 1 -S fd2b::f0 fd2b::1 823 824 # Give pfsync time to do its thing 825 sleep 2 826 827 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ 828 grep fd2b::f0 ; then 829 atf_fail "state not found on synced host" 830 fi 831} 832 833basic_ipv6_cleanup() 834{ 835 pfsynct_cleanup 836} 837 838atf_test_case "route_to" "cleanup" 839route_to_head() 840{ 841 atf_set descr 'Test route-to with default rule' 842 atf_set require.user root 843 atf_set require.progs scapy 844} 845 846route_to_body() 847{ 848 pfsynct_init 849 850 epair_sync=$(vnet_mkepair) 851 epair_one=$(vnet_mkepair) 852 epair_two=$(vnet_mkepair) 853 epair_out_one=$(vnet_mkepair) 854 epair_out_two=$(vnet_mkepair) 855 856 vnet_mkjail one ${epair_one}a ${epair_sync}a ${epair_out_one}a 857 vnet_mkjail two ${epair_two}a ${epair_sync}b ${epair_out_two}a 858 859 # pfsync interface 860 jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up 861 jexec one ifconfig ${epair_one}a 198.51.100.1/24 up 862 jexec one ifconfig ${epair_out_one}a 203.0.113.1/24 up 863 jexec one ifconfig ${epair_out_one}a name outif 864 jexec one sysctl net.inet.ip.forwarding=1 865 jexec one arp -s 203.0.113.254 00:01:02:03:04:05 866 jexec one ifconfig pfsync0 \ 867 syncdev ${epair_sync}a \ 868 maxupd 1 \ 869 up 870 871 jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up 872 jexec two ifconfig ${epair_two}a 198.51.100.2/24 up 873 jexec two ifconfig ${epair_out_two}a 203.0.113.2/24 up 874 #jexec two ifconfig ${epair_out_two}a name outif 875 jexec two sysctl net.inet.ip.forwarding=1 876 jexec two arp -s 203.0.113.254 00:01:02:03:04:05 877 jexec two ifconfig pfsync0 \ 878 syncdev ${epair_sync}b \ 879 maxupd 1 \ 880 up 881 882 # Enable pf! 883 jexec one pfctl -e 884 pft_set_rules one \ 885 "set skip on ${epair_sync}a" \ 886 "pass out route-to (outif 203.0.113.254)" 887 jexec two pfctl -e 888 889 # Make sure we have different rulesets so the synced state is associated with 890 # V_pf_default_rule 891 pft_set_rules two \ 892 "set skip on ${epair_sync}b" \ 893 "pass out route-to (outif 203.0.113.254)" \ 894 "pass out proto tcp" 895 896 ifconfig ${epair_one}b 198.51.100.254/24 up 897 ifconfig ${epair_two}b 198.51.100.253/24 up 898 route add -net 203.0.113.0/24 198.51.100.1 899 ifconfig ${epair_two}b up 900 ifconfig ${epair_out_one}b up 901 ifconfig ${epair_out_two}b up 902 903 atf_check -s exit:0 env PYTHONPATH=${common_dir} \ 904 ${common_dir}/pft_ping.py \ 905 --sendif ${epair_one}b \ 906 --fromaddr 198.51.100.254 \ 907 --to 203.0.113.254 \ 908 --recvif ${epair_out_one}b 909 910 # Allow time for sync 911 ifconfig ${epair_one}b inet 198.51.100.254 -alias 912 route del -net 203.0.113.0/24 198.51.100.1 913 route add -net 203.0.113.0/24 198.51.100.2 914 915 sleep 2 916 917 # Now try to trigger the state on the other pfsync member 918 env PYTHONPATH=${common_dir} \ 919 ${common_dir}/pft_ping.py \ 920 --sendif ${epair_two}b \ 921 --fromaddr 198.51.100.254 \ 922 --to 203.0.113.254 \ 923 --recvif ${epair_out_two}b 924 925 true 926} 927 928route_to_cleanup() 929{ 930 pfsynct_cleanup 931} 932 933atf_init_test_cases() 934{ 935 atf_add_test_case "basic" 936 atf_add_test_case "basic_defer" 937 atf_add_test_case "defer" 938 atf_add_test_case "bulk" 939 atf_add_test_case "pbr" 940 atf_add_test_case "pfsync_pbr" 941 atf_add_test_case "ipsec" 942 atf_add_test_case "timeout" 943 atf_add_test_case "basic_ipv6_unicast" 944 atf_add_test_case "basic_ipv6" 945 atf_add_test_case "route_to" 946} 947