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 339 bridge0=$(vnet_mkbridge) 340 bridge1=$(vnet_mkbridge) 341 bridge2=$(vnet_mkbridge) 342 343 epair_sync_gw_route_to=$(vnet_mkepair) 344 epair_sync_gw_reply_to=$(vnet_mkepair) 345 epair_client_bridge0=$(vnet_mkepair) 346 347 epair_gw_route_to_master_bridge0=$(vnet_mkepair) 348 epair_gw_route_to_backup_bridge0=$(vnet_mkepair) 349 epair_gw_route_to_master_bridge1=$(vnet_mkepair) 350 epair_gw_route_to_backup_bridge1=$(vnet_mkepair) 351 352 epair_gw_reply_to_master_bridge1=$(vnet_mkepair) 353 epair_gw_reply_to_backup_bridge1=$(vnet_mkepair) 354 epair_gw_reply_to_master_bridge2=$(vnet_mkepair) 355 epair_gw_reply_to_backup_bridge2=$(vnet_mkepair) 356 357 epair_server_bridge2=$(vnet_mkepair) 358 359 ifconfig ${bridge0} up 360 ifconfig ${epair_client_bridge0}b up 361 ifconfig ${epair_gw_route_to_master_bridge0}b up 362 ifconfig ${epair_gw_route_to_backup_bridge0}b up 363 ifconfig ${bridge0} \ 364 addm ${epair_client_bridge0}b \ 365 addm ${epair_gw_route_to_master_bridge0}b \ 366 addm ${epair_gw_route_to_backup_bridge0}b 367 368 ifconfig ${bridge1} up 369 ifconfig ${epair_gw_route_to_master_bridge1}b up 370 ifconfig ${epair_gw_route_to_backup_bridge1}b up 371 ifconfig ${epair_gw_reply_to_master_bridge1}b up 372 ifconfig ${epair_gw_reply_to_backup_bridge1}b up 373 ifconfig ${bridge1} \ 374 addm ${epair_gw_route_to_master_bridge1}b \ 375 addm ${epair_gw_route_to_backup_bridge1}b \ 376 addm ${epair_gw_reply_to_master_bridge1}b \ 377 addm ${epair_gw_reply_to_backup_bridge1}b 378 379 ifconfig ${bridge2} up 380 ifconfig ${epair_gw_reply_to_master_bridge2}b up 381 ifconfig ${epair_gw_reply_to_backup_bridge2}b up 382 ifconfig ${epair_server_bridge2}b up 383 ifconfig ${bridge2} \ 384 addm ${epair_gw_reply_to_master_bridge2}b \ 385 addm ${epair_gw_reply_to_backup_bridge2}b \ 386 addm ${epair_server_bridge2}b 387 388 vnet_mkjail client ${epair_client_bridge0}a 389 jexec client hostname client 390 vnet_mkjail gw_route_to_master \ 391 ${epair_gw_route_to_master_bridge0}a \ 392 ${epair_gw_route_to_master_bridge1}a \ 393 ${epair_sync_gw_route_to}a 394 jexec gw_route_to_master hostname gw_route_to_master 395 vnet_mkjail gw_route_to_backup \ 396 ${epair_gw_route_to_backup_bridge0}a \ 397 ${epair_gw_route_to_backup_bridge1}a \ 398 ${epair_sync_gw_route_to}b 399 jexec gw_route_to_backup hostname gw_route_to_backup 400 vnet_mkjail gw_reply_to_master \ 401 ${epair_gw_reply_to_master_bridge1}a \ 402 ${epair_gw_reply_to_master_bridge2}a \ 403 ${epair_sync_gw_reply_to}a 404 jexec gw_reply_to_master hostname gw_reply_to_master 405 vnet_mkjail gw_reply_to_backup \ 406 ${epair_gw_reply_to_backup_bridge1}a \ 407 ${epair_gw_reply_to_backup_bridge2}a \ 408 ${epair_sync_gw_reply_to}b 409 jexec gw_reply_to_backup hostname gw_reply_to_backup 410 vnet_mkjail server ${epair_server_bridge2}a 411 jexec server hostname server 412 413 jexec client ifconfig ${epair_client_bridge0}a inet 198.18.0.1/24 up 414 jexec client route add 198.18.2.0/24 198.18.0.10 415 416 jexec gw_route_to_master ifconfig ${epair_sync_gw_route_to}a \ 417 inet 198.19.10.1/24 up 418 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ 419 inet 198.18.0.8/24 up 420 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ 421 alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 50 422 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ 423 inet 198.18.1.8/24 up 424 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ 425 alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 50 426 jexec gw_route_to_master sysctl net.inet.ip.forwarding=1 427 jexec gw_route_to_master sysctl net.inet.carp.preempt=1 428 429 vnet_ifrename_jail gw_route_to_master ${epair_sync_gw_route_to}a if_pfsync 430 vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge0}a if_br0 431 vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge1}a if_br1 432 433 jexec gw_route_to_master ifconfig pfsync0 \ 434 syncpeer 198.19.10.2 \ 435 syncdev if_pfsync \ 436 maxupd 1 \ 437 up 438 pft_set_rules gw_route_to_master \ 439 "keep_state = 'tag auth_packet keep state'" \ 440 "set timeout { icmp.first 120, icmp.error 60 }" \ 441 "block log all" \ 442 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 443 "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ 444 "block drop in quick to 224.0.0.18/32" \ 445 "pass out quick tagged auth_packet keep state" \ 446 "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" 447 jexec gw_route_to_master pfctl -e 448 449 jexec gw_route_to_backup ifconfig ${epair_sync_gw_route_to}b \ 450 inet 198.19.10.2/24 up 451 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ 452 inet 198.18.0.9/24 up 453 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ 454 alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 100 455 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ 456 inet 198.18.1.9/24 up 457 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ 458 alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 100 459 jexec gw_route_to_backup sysctl net.inet.ip.forwarding=1 460 jexec gw_route_to_backup sysctl net.inet.carp.preempt=1 461 462 vnet_ifrename_jail gw_route_to_backup ${epair_sync_gw_route_to}b if_pfsync 463 vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge0}a if_br0 464 vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge1}a if_br1 465 466 jexec gw_route_to_backup ifconfig pfsync0 \ 467 syncpeer 198.19.10.1 \ 468 syncdev if_pfsync \ 469 up 470 pft_set_rules gw_route_to_backup \ 471 "keep_state = 'tag auth_packet keep state'" \ 472 "set timeout { icmp.first 120, icmp.error 60 }" \ 473 "block log all" \ 474 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 475 "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ 476 "block drop in quick to 224.0.0.18/32" \ 477 "pass out quick tagged auth_packet keep state" \ 478 "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" 479 jexec gw_route_to_backup pfctl -e 480 481 jexec gw_reply_to_master ifconfig ${epair_sync_gw_reply_to}a \ 482 inet 198.19.20.1/24 up 483 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ 484 inet 198.18.1.18/24 up 485 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ 486 alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 50 487 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ 488 inet 198.18.2.18/24 up 489 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ 490 alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 50 491 jexec gw_reply_to_master sysctl net.inet.ip.forwarding=1 492 jexec gw_reply_to_master sysctl net.inet.carp.preempt=1 493 494 vnet_ifrename_jail gw_reply_to_master ${epair_sync_gw_reply_to}a if_pfsync 495 vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge1}a if_br1 496 vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge2}a if_br2 497 498 jexec gw_reply_to_master ifconfig pfsync0 \ 499 syncpeer 198.19.20.2 \ 500 syncdev if_pfsync \ 501 maxupd 1 \ 502 up 503 pft_set_rules gw_reply_to_master \ 504 "set timeout { icmp.first 120, icmp.error 60 }" \ 505 "block log all" \ 506 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 507 "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ 508 "block drop in quick to 224.0.0.18/32" \ 509 "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ 510 "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" 511 jexec gw_reply_to_master pfctl -e 512 513 jexec gw_reply_to_backup ifconfig ${epair_sync_gw_reply_to}b \ 514 inet 198.19.20.2/24 up 515 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ 516 inet 198.18.1.19/24 up 517 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ 518 alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 100 519 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ 520 inet 198.18.2.19/24 up 521 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ 522 alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 100 523 jexec gw_reply_to_backup sysctl net.inet.ip.forwarding=1 524 jexec gw_reply_to_backup sysctl net.inet.carp.preempt=1 525 526 vnet_ifrename_jail gw_reply_to_backup ${epair_sync_gw_reply_to}b if_pfsync 527 vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge1}a if_br1 528 vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge2}a if_br2 529 530 jexec gw_reply_to_backup ifconfig pfsync0 \ 531 syncpeer 198.19.20.1 \ 532 syncdev if_pfsync \ 533 up 534 pft_set_rules gw_reply_to_backup \ 535 "set timeout { icmp.first 120, icmp.error 60 }" \ 536 "block log all" \ 537 "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ 538 "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ 539 "block drop in quick to 224.0.0.18/32" \ 540 "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ 541 "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" 542 jexec gw_reply_to_backup pfctl -e 543 544 jexec server ifconfig ${epair_server_bridge2}a inet 198.18.2.1/24 up 545 jexec server route add 198.18.0.0/24 198.18.2.20 546 547 # Waiting for platform to settle 548 while ! jexec gw_route_to_backup ifconfig | grep 'carp: BACKUP' 549 do 550 sleep 1 551 done 552 while ! jexec gw_reply_to_backup ifconfig | grep 'carp: BACKUP' 553 do 554 sleep 1 555 done 556 while ! jexec client ping -c 10 198.18.2.1 | grep ', 0.0% packet loss' 557 do 558 sleep 1 559 done 560 561 # Checking cluster members pf.conf checksums match 562 gw_route_to_master_checksum=$(jexec gw_route_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 563 gw_route_to_backup_checksum=$(jexec gw_route_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 564 gw_reply_to_master_checksum=$(jexec gw_reply_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 565 gw_reply_to_backup_checksum=$(jexec gw_reply_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) 566 if [ "$gw_route_to_master_checksum" != "$gw_route_to_backup_checksum" ] 567 then 568 atf_fail "gw_route_to cluster members pf.conf do not match each others" 569 fi 570 if [ "$gw_reply_to_master_checksum" != "$gw_reply_to_backup_checksum" ] 571 then 572 atf_fail "gw_reply_to cluster members pf.conf do not match each others" 573 fi 574 575 # Creating state entries 576 (jexec client ping -c 10 198.18.2.1 >ping.stdout) & 577 578 if [ "$1" = "backup_promotion" ] 579 then 580 sleep 1 581 jexec gw_route_to_backup ifconfig if_br0 vhid 10 advskew 0 582 jexec gw_route_to_backup ifconfig if_br1 vhid 11 advskew 0 583 jexec gw_reply_to_backup ifconfig if_br1 vhid 21 advskew 0 584 jexec gw_reply_to_backup ifconfig if_br2 vhid 22 advskew 0 585 fi 586 while ! grep -q -e 'packet loss' ping.stdout 587 do 588 sleep 1 589 done 590 591 atf_check -s exit:0 -e ignore -o ignore grep ', 0.0% packet loss' ping.stdout 592} 593 594pbr_common_cleanup() 595{ 596 pft_cleanup 597} 598 599atf_test_case "ipsec" "cleanup" 600ipsec_head() 601{ 602 atf_set descr 'Transport pfsync over IPSec' 603 atf_set require.user root 604} 605 606ipsec_body() 607{ 608 if ! sysctl -q kern.features.ipsec >/dev/null ; then 609 atf_skip "This test requires ipsec" 610 fi 611 612 # Run the common test, to set up pfsync 613 common_body 614 615 # But we want unicast pfsync 616 jexec one ifconfig pfsync0 syncpeer 192.0.2.2 617 jexec two ifconfig pfsync0 syncpeer 192.0.2.1 618 619 # Flush existing states 620 jexec one pfctl -Fs 621 jexec two pfctl -Fs 622 623 # Now define an ipsec policy to run over the epair_sync interfaces 624 echo "flush; 625 spdflush; 626 spdadd 192.0.2.1/32 192.0.2.2/32 any -P out ipsec esp/transport//require; 627 spdadd 192.0.2.2/32 192.0.2.1/32 any -P in ipsec esp/transport//require; 628 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; 629 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ 630 | jexec one setkey -c 631 632 echo "flush; 633 spdflush; 634 spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; 635 spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; 636 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567891\"; 637 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567891\";" \ 638 | jexec two setkey -c 639 640 # We've set incompatible keys, so pfsync will be broken. 641 ping -c 1 -S 198.51.100.254 198.51.100.1 642 643 # Give pfsync time to do its thing 644 sleep 2 645 646 if jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 647 grep 198.51.100.2 ; then 648 atf_fail "state synced although IPSec should have prevented it" 649 fi 650 651 # Flush existing states 652 jexec one pfctl -Fs 653 jexec two pfctl -Fs 654 655 # Fix the IPSec key to match 656 echo "flush; 657 spdflush; 658 spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; 659 spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; 660 add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; 661 add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ 662 | jexec two setkey -c 663 664 ping -c 1 -S 198.51.100.254 198.51.100.1 665 666 # Give pfsync time to do its thing 667 sleep 2 668 669 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ 670 grep 198.51.100.2 ; then 671 atf_fail "state not found on synced host" 672 fi 673} 674 675ipsec_cleanup() 676{ 677 pft_cleanup 678} 679 680atf_test_case "timeout" "cleanup" 681timeout_head() 682{ 683 atf_set descr 'Trigger pfsync_timeout()' 684 atf_set require.user root 685} 686 687timeout_body() 688{ 689 pft_init 690 691 vnet_mkjail one 692 693 jexec one ifconfig lo0 127.0.0.1/8 up 694 jexec one ifconfig lo0 inet6 ::1/128 up 695 696 pft_set_rules one \ 697 "pass all" 698 jexec one pfctl -e 699 jexec one ifconfig pfsync0 defer up 700 701 jexec one ping -c 1 ::1 702 jexec one ping -c 1 127.0.0.1 703 704 # Give pfsync_timeout() time to fire (a callout on a 1 second delay) 705 sleep 2 706} 707 708timeout_cleanup() 709{ 710 pft_cleanup 711} 712 713atf_test_case "basic_ipv6_unicast" "cleanup" 714basic_ipv6_unicast_head() 715{ 716 atf_set descr 'Basic pfsync test (IPv6)' 717 atf_set require.user root 718} 719 720basic_ipv6_unicast_body() 721{ 722 pfsynct_init 723 724 epair_sync=$(vnet_mkepair) 725 epair_one=$(vnet_mkepair) 726 epair_two=$(vnet_mkepair) 727 728 vnet_mkjail one ${epair_one}a ${epair_sync}a 729 vnet_mkjail two ${epair_two}a ${epair_sync}b 730 731 # pfsync interface 732 jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up 733 jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up 734 jexec one ifconfig pfsync0 \ 735 syncdev ${epair_sync}a \ 736 syncpeer fd2c::2 \ 737 maxupd 1 \ 738 up 739 jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up 740 jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up 741 jexec two ifconfig pfsync0 \ 742 syncdev ${epair_sync}b \ 743 syncpeer fd2c::1 \ 744 maxupd 1 \ 745 up 746 747 # Enable pf! 748 jexec one pfctl -e 749 pft_set_rules one \ 750 "block on ${epair_sync}a inet" \ 751 "pass out keep state" 752 jexec two pfctl -e 753 pft_set_rules two \ 754 "block on ${epair_sync}b inet" \ 755 "pass out keep state" 756 757 ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up 758 759 ping6 -c 1 -S fd2b::f0 fd2b::1 760 761 # Give pfsync time to do its thing 762 sleep 2 763 764 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ 765 grep fd2b::f0 ; then 766 atf_fail "state not found on synced host" 767 fi 768} 769 770basic_ipv6_unicast_cleanup() 771{ 772 pfsynct_cleanup 773} 774 775atf_test_case "basic_ipv6" "cleanup" 776basic_ipv6_head() 777{ 778 atf_set descr 'Basic pfsync test (IPv6)' 779 atf_set require.user root 780} 781 782basic_ipv6_body() 783{ 784 pfsynct_init 785 786 epair_sync=$(vnet_mkepair) 787 epair_one=$(vnet_mkepair) 788 epair_two=$(vnet_mkepair) 789 790 vnet_mkjail one ${epair_one}a ${epair_sync}a 791 vnet_mkjail two ${epair_two}a ${epair_sync}b 792 793 # pfsync interface 794 jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up 795 jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up 796 jexec one ifconfig pfsync0 \ 797 syncdev ${epair_sync}a \ 798 syncpeer ff12::f0 \ 799 maxupd 1 \ 800 up 801 jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up 802 jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up 803 jexec two ifconfig pfsync0 \ 804 syncdev ${epair_sync}b \ 805 syncpeer ff12::f0 \ 806 maxupd 1 \ 807 up 808 809 # Enable pf! 810 jexec one pfctl -e 811 pft_set_rules one \ 812 "block on ${epair_sync}a inet" \ 813 "pass out keep state" 814 jexec two pfctl -e 815 pft_set_rules two \ 816 "block on ${epair_sync}b inet" \ 817 "pass out keep state" 818 819 ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up 820 821 ping6 -c 1 -S fd2b::f0 fd2b::1 822 823 # Give pfsync time to do its thing 824 sleep 2 825 826 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ 827 grep fd2b::f0 ; then 828 atf_fail "state not found on synced host" 829 fi 830} 831 832basic_ipv6_cleanup() 833{ 834 pfsynct_cleanup 835} 836 837atf_test_case "route_to" "cleanup" 838route_to_head() 839{ 840 atf_set descr 'Test route-to with default rule' 841 atf_set require.user root 842 atf_set require.progs scapy 843} 844 845route_to_body() 846{ 847 pfsynct_init 848 849 epair_sync=$(vnet_mkepair) 850 epair_one=$(vnet_mkepair) 851 epair_two=$(vnet_mkepair) 852 epair_out_one=$(vnet_mkepair) 853 epair_out_two=$(vnet_mkepair) 854 855 vnet_mkjail one ${epair_one}a ${epair_sync}a ${epair_out_one}a 856 vnet_mkjail two ${epair_two}a ${epair_sync}b ${epair_out_two}a 857 858 # pfsync interface 859 jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up 860 jexec one ifconfig ${epair_one}a 198.51.100.1/24 up 861 jexec one ifconfig ${epair_out_one}a 203.0.113.1/24 up 862 jexec one ifconfig ${epair_out_one}a name outif 863 jexec one sysctl net.inet.ip.forwarding=1 864 jexec one arp -s 203.0.113.254 00:01:02:03:04:05 865 jexec one ifconfig pfsync0 \ 866 syncdev ${epair_sync}a \ 867 maxupd 1 \ 868 up 869 870 jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up 871 jexec two ifconfig ${epair_two}a 198.51.100.2/24 up 872 jexec two ifconfig ${epair_out_two}a 203.0.113.2/24 up 873 #jexec two ifconfig ${epair_out_two}a name outif 874 jexec two sysctl net.inet.ip.forwarding=1 875 jexec two arp -s 203.0.113.254 00:01:02:03:04:05 876 jexec two ifconfig pfsync0 \ 877 syncdev ${epair_sync}b \ 878 maxupd 1 \ 879 up 880 881 # Enable pf! 882 jexec one pfctl -e 883 pft_set_rules one \ 884 "set skip on ${epair_sync}a" \ 885 "pass out route-to (outif 203.0.113.254)" 886 jexec two pfctl -e 887 888 # Make sure we have different rulesets so the synced state is associated with 889 # V_pf_default_rule 890 pft_set_rules two \ 891 "set skip on ${epair_sync}b" \ 892 "pass out route-to (outif 203.0.113.254)" \ 893 "pass out proto tcp" 894 895 ifconfig ${epair_one}b 198.51.100.254/24 up 896 ifconfig ${epair_two}b 198.51.100.253/24 up 897 route add -net 203.0.113.0/24 198.51.100.1 898 ifconfig ${epair_two}b up 899 ifconfig ${epair_out_one}b up 900 ifconfig ${epair_out_two}b up 901 902 atf_check -s exit:0 env PYTHONPATH=${common_dir} \ 903 ${common_dir}/pft_ping.py \ 904 --sendif ${epair_one}b \ 905 --fromaddr 198.51.100.254 \ 906 --to 203.0.113.254 \ 907 --recvif ${epair_out_one}b 908 909 # Allow time for sync 910 ifconfig ${epair_one}b inet 198.51.100.254 -alias 911 route del -net 203.0.113.0/24 198.51.100.1 912 route add -net 203.0.113.0/24 198.51.100.2 913 914 sleep 2 915 916 # Now try to trigger the state on the other pfsync member 917 env PYTHONPATH=${common_dir} \ 918 ${common_dir}/pft_ping.py \ 919 --sendif ${epair_two}b \ 920 --fromaddr 198.51.100.254 \ 921 --to 203.0.113.254 \ 922 --recvif ${epair_out_two}b 923 924 true 925} 926 927route_to_cleanup() 928{ 929 pfsynct_cleanup 930} 931 932atf_init_test_cases() 933{ 934 atf_add_test_case "basic" 935 atf_add_test_case "basic_defer" 936 atf_add_test_case "defer" 937 atf_add_test_case "bulk" 938 atf_add_test_case "pbr" 939 atf_add_test_case "pfsync_pbr" 940 atf_add_test_case "ipsec" 941 atf_add_test_case "timeout" 942 atf_add_test_case "basic_ipv6_unicast" 943 atf_add_test_case "basic_ipv6" 944 atf_add_test_case "route_to" 945} 946