1 # $NetBSD: t_arp.sh,v 1.49 2025/08/18 06:48:29 ozaki-r Exp $ 2 # 3 # Copyright (c) 2015 The NetBSD Foundation, Inc. 4 # 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 # POSSIBILITY OF SUCH DAMAGE. 26 # 27 28 SOCKSRC=unix://commsock1 29 SOCKDST=unix://commsock2 30 IP4SRC=10.0.1.1 31 IP4SRC2=10.0.1.5 32 IP4NET=10.0.1.0 33 IP4DST=10.0.1.2 34 IP4DST_PROXYARP1=10.0.1.3 35 IP4DST_PROXYARP2=10.0.1.4 36 IP4DST_FAIL1=10.0.1.99 37 IP4DST_FAIL2=10.0.99.99 38 39 DEBUG=${DEBUG:-false} 40 TIMEOUT=1 41 42 setup_dst_server() 43 { 44 45 rump_server_add_iface $SOCKDST shmif0 bus1 46 export RUMP_SERVER=$SOCKDST 47 atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24 48 atf_check -s exit:0 rump.ifconfig shmif0 up 49 atf_check -s exit:0 rump.ifconfig -w 10 50 51 $DEBUG && rump.ifconfig shmif0 52 $DEBUG && rump.arp -n -a 53 $DEBUG && rump.netstat -nr -f inet 54 } 55 56 setup_src_server() 57 { 58 local keep=${1:-0} 59 60 export RUMP_SERVER=$SOCKSRC 61 62 # Shorten the expire time of cache entries 63 if [ $keep != 0 ]; then 64 # Convert to ms 65 keep=$(($keep * 1000)) 66 atf_check -s exit:0 -o ignore \ 67 rump.sysctl -w net.inet.arp.nd_reachable=$keep 68 fi 69 70 # Setup an interface 71 rump_server_add_iface $SOCKSRC shmif0 bus1 72 atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24 73 atf_check -s exit:0 rump.ifconfig shmif0 up 74 atf_check -s exit:0 rump.ifconfig -w 10 75 76 # Sanity check 77 $DEBUG && rump.ifconfig shmif0 78 $DEBUG && rump.arp -n -a 79 $DEBUG && rump.netstat -nr -f inet 80 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4SRC 81 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 82 } 83 84 get_timeout() 85 { 86 local addr="$1" 87 local timeout=$(env RUMP_SERVER=$SOCKSRC rump.arp -n $addr |grep $addr|awk '{print $7;}') 88 timeout=${timeout%s} 89 echo $timeout 90 } 91 92 test_cache_expiration() 93 { 94 local arp_keep=7 95 96 rump_server_start $SOCKSRC 97 rump_server_start $SOCKDST 98 99 setup_dst_server 100 setup_src_server $arp_keep 101 102 # Make a permanent cache entry to avoid sending an NS packet disturbing 103 # the test 104 macaddr=$(get_macaddr $SOCKSRC shmif0) 105 export RUMP_SERVER=$SOCKDST 106 atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr 107 108 export RUMP_SERVER=$SOCKSRC 109 110 # 111 # Check if a cache is expired expectedly 112 # 113 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST 114 115 $DEBUG && rump.arp -n -a 116 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.arp -n $IP4SRC 117 # Should be cached 118 atf_check -s exit:0 -o not-match:'permanent' rump.arp -n $IP4DST 119 120 timeout=$(get_timeout $IP4DST) 121 122 atf_check -s exit:0 sleep $(($timeout + 1)) 123 124 $DEBUG && rump.arp -n -a 125 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.arp -n $IP4SRC 126 # Expired but remains until GC sweaps it (1 day) 127 atf_check -s exit:0 -o match:"$ONEDAYISH" rump.arp -n $IP4DST 128 129 rump_server_destroy_ifaces 130 } 131 132 check_arp_static_entry() 133 { 134 local ip=$1 135 local mac=$2 136 local type=$3 137 local flags= 138 139 atf_check -s exit:0 -o match:"$mac" rump.arp -n $ip 140 if [ $type = 'permanent' ]; then 141 atf_check -s exit:0 -o match:'permanent' rump.arp -n $ip 142 check_route $ip "$mac" UHLS shmif0 143 else 144 atf_check -s exit:0 -o not-match:'permanent' rump.arp -n $ip 145 check_route $ip "$mac" UHL shmif0 146 fi 147 } 148 149 test_command() 150 { 151 local arp_keep=5 152 local bonus=2 153 154 rump_server_start $SOCKSRC 155 rump_server_start $SOCKDST 156 157 setup_dst_server 158 setup_src_server $arp_keep 159 160 export RUMP_SERVER=$SOCKSRC 161 162 # Add and delete a static entry 163 $DEBUG && rump.arp -n -a 164 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 165 $DEBUG && rump.arp -n -a 166 $DEBUG && rump.netstat -nr -f inet 167 check_arp_static_entry 10.0.1.10 'b2:a0:20:00:00:10' permanent 168 atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10 169 $DEBUG && rump.arp -n -a 170 $DEBUG && rump.netstat -nr -f inet 171 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 172 check_route_no_entry 10.0.1.10 173 174 # Add multiple entries via a file 175 cat - > ./list <<-EOF 176 10.0.1.11 b2:a0:20:00:00:11 177 10.0.1.12 b2:a0:20:00:00:12 178 10.0.1.13 b2:a0:20:00:00:13 179 10.0.1.14 b2:a0:20:00:00:14 180 10.0.1.15 b2:a0:20:00:00:15 181 EOF 182 $DEBUG && rump.arp -n -a 183 $DEBUG && rump.netstat -nr -f inet 184 atf_check -s exit:0 -o ignore rump.arp -f ./list 185 $DEBUG && rump.arp -n -a 186 $DEBUG && rump.netstat -nr -f inet 187 check_arp_static_entry 10.0.1.11 'b2:a0:20:00:00:11' permanent 188 check_arp_static_entry 10.0.1.12 'b2:a0:20:00:00:12' permanent 189 check_arp_static_entry 10.0.1.13 'b2:a0:20:00:00:13' permanent 190 check_arp_static_entry 10.0.1.14 'b2:a0:20:00:00:14' permanent 191 check_arp_static_entry 10.0.1.15 'b2:a0:20:00:00:15' permanent 192 193 # Test arp -a 194 atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a 195 atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a 196 atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a 197 atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a 198 atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a 199 200 # Flush all entries 201 $DEBUG && rump.arp -n -a 202 $DEBUG && rump.netstat -nr -f inet 203 atf_check -s exit:0 -o ignore rump.arp -d -a 204 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11 205 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12 206 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13 207 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14 208 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15 209 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1 210 check_route_no_entry 10.0.1.11 211 check_route_no_entry 10.0.1.12 212 check_route_no_entry 10.0.1.13 213 check_route_no_entry 10.0.1.14 214 check_route_no_entry 10.0.1.15 215 216 # Test temp option 217 $DEBUG && rump.arp -n -a 218 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp 219 $DEBUG && rump.arp -n -a 220 $DEBUG && rump.netstat -nr -f inet 221 check_arp_static_entry 10.0.1.10 'b2:a0:20:00:00:10' temp 222 223 # Hm? the cache doesn't expire... 224 #atf_check -s exit:0 sleep $(($arp_keep + $bonus)) 225 #$DEBUG && rump.arp -n -a 226 #$DEBUG && rump.netstat -nr -f inet 227 #atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 228 229 rump_server_destroy_ifaces 230 } 231 232 make_pkt_str_arpreq() 233 { 234 local target=$1 235 local sender=$2 236 pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP \(0x0806\), length 42:" 237 pkt="$pkt Request who-has $target tell $sender, length 28" 238 echo $pkt 239 } 240 241 test_garp_common() 242 { 243 local no_dad=$1 244 local pkt= 245 246 rump_server_start $SOCKSRC 247 248 export RUMP_SERVER=$SOCKSRC 249 250 if $no_dad; then 251 atf_check -s exit:0 -o match:'3 -> 0' \ 252 rump.sysctl -w net.inet.ip.dad_count=0 253 fi 254 255 # Setup an interface 256 rump_server_add_iface $SOCKSRC shmif0 bus1 257 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 258 atf_check -s exit:0 rump.ifconfig shmif0 up 259 $DEBUG && rump.ifconfig shmif0 260 261 atf_check -s exit:0 sleep 1 262 extract_new_packets bus1 > ./out 263 264 # 265 # Assign an address to an interface without IFF_UP 266 # 267 # A GARP packet is sent for the primary address 268 pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1) 269 atf_check -s exit:0 -o match:"$pkt" cat ./out 270 271 atf_check -s exit:0 rump.ifconfig shmif0 down 272 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias 273 274 atf_check -s exit:0 sleep 1 275 extract_new_packets bus1 > ./out 276 277 # A GARP packet is sent for the alias address 278 pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2) 279 atf_check -s exit:0 -o match:"$pkt" cat ./out 280 281 # Clean up 282 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 delete 283 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 delete 284 285 # 286 # Assign an address to an interface with IFF_UP 287 # 288 atf_check -s exit:0 rump.ifconfig shmif0 up 289 290 # Primary address 291 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24 292 293 atf_check -s exit:0 sleep 1 294 extract_new_packets bus1 > ./out 295 296 pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) 297 if $no_dad; then 298 # A GARP packet is sent 299 atf_check -s exit:0 -o match:"$pkt" cat ./out 300 else 301 # No GARP packet is sent 302 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 303 fi 304 305 # Alias address 306 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias 307 308 atf_check -s exit:0 sleep 1 309 extract_new_packets bus1 > ./out 310 311 pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) 312 if $no_dad; then 313 # A GARP packet is sent 314 atf_check -s exit:0 -o match:"$pkt" cat ./out 315 else 316 # No GARP packet is sent 317 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 318 fi 319 320 # 321 # GARP on Link up 322 # 323 atf_check -s exit:0 rump.ifconfig shmif0 media none 324 extract_new_packets bus1 > ./out 325 atf_check -s exit:0 rump.ifconfig shmif0 media auto 326 327 atf_check -s exit:0 sleep 1 328 extract_new_packets bus1 > ./out 329 330 if $no_dad; then 331 # A GARP packet is sent for both primary and alias addresses. 332 pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) 333 atf_check -s exit:0 -o match:"$pkt" cat ./out 334 pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) 335 atf_check -s exit:0 -o match:"$pkt" cat ./out 336 else 337 # No GARP is sent. 338 pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) 339 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 340 pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) 341 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 342 # DAD packets are sent instead. 343 pkt=$(make_pkt_str_arpreq 10.0.0.3 0.0.0.0) 344 atf_check -s exit:0 -o match:"$pkt" cat ./out 345 pkt=$(make_pkt_str_arpreq 10.0.0.4 0.0.0.0) 346 atf_check -s exit:0 -o match:"$pkt" cat ./out 347 fi 348 349 rump_server_destroy_ifaces 350 } 351 352 test_garp() 353 { 354 355 test_garp_common false 356 } 357 358 test_garp_without_dad() 359 { 360 361 test_garp_common true 362 } 363 364 test_cache_overwriting() 365 { 366 367 rump_server_start $SOCKSRC 368 rump_server_start $SOCKDST 369 370 setup_dst_server 371 setup_src_server 372 373 export RUMP_SERVER=$SOCKSRC 374 375 # Cannot overwrite a permanent cache 376 atf_check -s exit:0 rump.arp -s $IP4DST b2:a0:20:00:00:ff 377 $DEBUG && rump.arp -n -a 378 atf_check -s not-exit:0 -e match:'File exists' \ 379 rump.arp -s $IP4DST b2:a0:20:00:00:fe 380 # cleanup 381 atf_check -s exit:0 rump.arp -d $IP4DST 382 383 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST 384 $DEBUG && rump.arp -n -a 385 # Can overwrite a dynamic cache 386 atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00 387 $DEBUG && rump.arp -n -a 388 atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST 389 atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST 390 391 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp 392 $DEBUG && rump.arp -n -a 393 atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 394 atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10 395 # Can overwrite a temp cache 396 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff 397 atf_check -s exit:0 -o match:'b2:a0:20:00:00:ff' rump.arp -n 10.0.1.10 398 $DEBUG && rump.arp -n -a 399 400 rump_server_destroy_ifaces 401 } 402 403 make_pkt_str_arprep() 404 { 405 local ip=$1 406 local mac=$2 407 pkt="ethertype ARP (0x0806), length 42: " 408 pkt="Reply $ip is-at $mac, length 28" 409 echo $pkt 410 } 411 412 make_pkt_str_garp() 413 { 414 local ip=$1 415 local mac=$2 416 local pkt= 417 pkt="$mac > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806)," 418 pkt="$pkt length 42: Request who-has $ip tell $ip, length 28" 419 echo $pkt 420 } 421 422 test_proxy_arp() 423 { 424 local opts= title= flags= 425 local type=$1 426 427 rump_server_start $SOCKSRC 428 rump_server_fs_start $SOCKDST tap 429 430 setup_dst_server 431 setup_src_server 432 433 export RUMP_SERVER=$SOCKDST 434 atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1 435 macaddr_dst=$(get_macaddr $SOCKDST shmif0) 436 437 if [ "$type" = "pub" ]; then 438 opts="pub" 439 else 440 opts="pub proxy" 441 fi 442 # Always proxy only since migrating to lltable/llentry 443 title='published \(proxy only\)' 444 445 # 446 # Test#1: First setup an endpoint then create proxy arp entry 447 # 448 export RUMP_SERVER=$SOCKDST 449 rump_server_add_iface $SOCKDST tap1 450 atf_check -s exit:0 rump.ifconfig tap1 $IP4DST_PROXYARP1/24 up 451 atf_check -s exit:0 rump.ifconfig -w 10 452 453 # Try to ping (should fail w/o proxy arp) 454 export RUMP_SERVER=$SOCKSRC 455 atf_check -s not-exit:0 -o ignore -e ignore \ 456 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 457 # Remove ARP entry as it may hang around in WAITDELETE a few seconds 458 atf_check -s ignore rump.arp -d $IP4DST_PROXYARP1 459 460 # Flushing 461 extract_new_packets bus1 > ./out 462 463 # Set up proxy ARP entry 464 export RUMP_SERVER=$SOCKDST 465 atf_check -s exit:0 -o ignore \ 466 rump.arp -s $IP4DST_PROXYARP1 $macaddr_dst $opts 467 atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP1 468 469 # Try to ping 470 export RUMP_SERVER=$SOCKSRC 471 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 472 473 extract_new_packets bus1 > ./out 474 $DEBUG && cat ./out 475 476 pkt1=$(make_pkt_str_arprep $IP4DST_PROXYARP1 $macaddr_dst) 477 pkt2=$(make_pkt_str_garp $IP4DST_PROXYARP1 $macaddr_dst) 478 atf_check -s exit:0 -x "cat ./out |grep -q -e '$pkt1' -e '$pkt2'" 479 480 # 481 # Test#2: Create proxy arp entry then set up an endpoint 482 # 483 export RUMP_SERVER=$SOCKDST 484 atf_check -s exit:0 -o ignore \ 485 rump.arp -s $IP4DST_PROXYARP2 $macaddr_dst $opts 486 atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP2 487 $DEBUG && rump.netstat -nr -f inet 488 489 # Try to ping (should fail because no endpoint exists) 490 export RUMP_SERVER=$SOCKSRC 491 atf_check -s not-exit:0 -o ignore -e ignore \ 492 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 493 # Remove ARP entry as it may hang around in WAITDELETE a few seconds 494 atf_check -s ignore rump.arp -d $IP4DST_PROXYARP2 495 496 extract_new_packets bus1 > ./out 497 $DEBUG && cat ./out 498 499 # ARP reply should be sent 500 pkt=$(make_pkt_str_arprep $IP4DST_PROXYARP2 $macaddr_dst) 501 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" 502 503 export RUMP_SERVER=$SOCKDST 504 rump_server_add_iface $SOCKDST tap2 505 atf_check -s exit:0 rump.ifconfig tap2 $IP4DST_PROXYARP2/24 up 506 atf_check -s exit:0 rump.ifconfig -w 10 507 508 # Try to ping 509 export RUMP_SERVER=$SOCKSRC 510 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 511 } 512 513 test_proxy_arp_pub() 514 { 515 516 test_proxy_arp pub 517 rump_server_destroy_ifaces 518 } 519 520 test_proxy_arp_pubproxy() 521 { 522 523 test_proxy_arp pubproxy 524 rump_server_destroy_ifaces 525 } 526 527 test_link_activation() 528 { 529 530 rump_server_start $SOCKSRC 531 rump_server_start $SOCKDST 532 533 setup_dst_server 534 setup_src_server 535 536 # flush old packets 537 extract_new_packets bus1 > ./out 538 539 export RUMP_SERVER=$SOCKSRC 540 541 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 542 b2:a1:00:00:00:01 543 544 atf_check -s exit:0 sleep 1 545 extract_new_packets bus1 > ./out 546 $DEBUG && cat ./out 547 548 pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) 549 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 550 551 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 552 b2:a1:00:00:00:02 active 553 554 atf_check -s exit:0 sleep 1 555 extract_new_packets bus1 > ./out 556 $DEBUG && cat ./out 557 558 pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) 559 atf_check -s exit:0 -o match:"b2:a1:00:00:00:02 $pkt" cat ./out 560 561 rump_server_destroy_ifaces 562 } 563 564 test_static() 565 { 566 local macaddr_src= 567 568 rump_server_start $SOCKSRC 569 rump_server_start $SOCKDST 570 571 setup_dst_server 572 setup_src_server 573 574 macaddr_src=$(get_macaddr $SOCKSRC shmif0) 575 576 # Set a (valid) static ARP entry for the src server 577 export RUMP_SERVER=$SOCKDST 578 $DEBUG && rump.arp -n -a 579 atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr_src 580 $DEBUG && rump.arp -n -a 581 582 # Test receiving an ARP request with the static ARP entry (as spa/sha) 583 export RUMP_SERVER=$SOCKSRC 584 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 585 586 rump_server_destroy_ifaces 587 } 588 589 test_rtm() 590 { 591 local macaddr_src= macaddr_dst= 592 local file=./tmp 593 local pid= hdr= what= addr= 594 595 rump_server_start $SOCKSRC 596 rump_server_start $SOCKDST 597 598 setup_dst_server 599 setup_src_server 600 601 macaddr_src=$(get_macaddr $SOCKSRC shmif0) 602 macaddr_dst=$(get_macaddr $SOCKDST shmif0) 603 604 export RUMP_SERVER=$SOCKSRC 605 606 # Test ping and a resulting routing message (RTM_ADD) 607 rump.route -n monitor -c 1 > $file & 608 pid=$! 609 sleep 1 610 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 611 wait $pid 612 $DEBUG && cat $file 613 614 hdr="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>" 615 what="<DST,GATEWAY>" 616 addr="$IP4DST $macaddr_dst" 617 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \ 618 cat $file 619 620 # Test ping and a resulting routing message (RTM_MISS) on subnet 621 rump.route -n monitor -c 1 > $file & 622 pid=$! 623 sleep 1 624 atf_check -s exit:2 -o ignore -e ignore \ 625 rump.ping -n -w 1 -c 1 $IP4DST_FAIL1 626 wait $pid 627 $DEBUG && cat $file 628 629 hdr="RTM_MISS.+<DONE>" 630 what="<DST,GATEWAY,AUTHOR>" 631 addr="$IP4DST_FAIL1 link#2 $IP4SRC" 632 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \ 633 cat $file 634 635 # Test ping and a resulting routing message (RTM_MISS) off subnet 636 rump.route -n monitor -c 1 > $file & 637 pid=$! 638 sleep 1 639 atf_check -s exit:2 -o ignore -e ignore \ 640 rump.ping -n -w 1 -c 1 $IP4DST_FAIL2 641 wait $pid 642 $DEBUG && cat $file 643 644 hdr="RTM_MISS.+<DONE>" 645 what="<DST>" 646 addr="$IP4DST_FAIL2" 647 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \ 648 cat $file 649 650 # Test arp -d and resulting routing messages (RTM_DELETE) 651 rump.route -n monitor -c 1 > $file & 652 pid=$! 653 sleep 1 654 atf_check -s exit:0 -o ignore rump.arp -d $IP4DST 655 wait $pid 656 $DEBUG && cat $file 657 658 hdr="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>" 659 what="<DST,GATEWAY>" 660 addr="$IP4DST $macaddr_dst" 661 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \ 662 grep -A 3 RTM_DELETE $file 663 664 rump_server_destroy_ifaces 665 } 666 667 test_purge_on_route_change() 668 { 669 670 rump_server_start $SOCKSRC 671 rump_server_start $SOCKDST 672 673 setup_dst_server 674 setup_src_server 675 676 rump_server_add_iface $SOCKSRC shmif1 bus1 677 export RUMP_SERVER=$SOCKSRC 678 atf_check -s exit:0 rump.ifconfig shmif1 inet $IP4SRC2/24 679 atf_check -s exit:0 rump.ifconfig -w 10 680 681 $DEBUG && rump.netstat -nr -f inet 682 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 683 $DEBUG && rump.arp -na 684 atf_check -s exit:0 -o ignore \ 685 rump.route change -net $IP4NET -ifp shmif1 686 $DEBUG && rump.netstat -nr -f inet 687 $DEBUG && rump.arp -na 688 # The entry was already removed on route change 689 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 690 691 rump_server_destroy_ifaces 692 } 693 694 test_purge_on_route_delete() 695 { 696 697 rump_server_start $SOCKSRC 698 rump_server_start $SOCKDST 699 700 setup_dst_server 701 setup_src_server 702 703 $DEBUG && rump.netstat -nr -f inet 704 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 705 $DEBUG && rump.arp -na 706 707 atf_check -s exit:0 -o ignore rump.route delete -net $IP4NET 708 $DEBUG && rump.netstat -nr -f inet 709 $DEBUG && rump.arp -na 710 711 # The entry was already removed on route delete 712 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 713 714 rump_server_destroy_ifaces 715 } 716 717 test_purge_on_ifdown() 718 { 719 720 rump_server_start $SOCKSRC 721 rump_server_start $SOCKDST 722 723 setup_dst_server 724 setup_src_server 725 726 $DEBUG && rump.netstat -nr -f inet 727 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 728 atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST 729 730 # Shutdown the interface 731 atf_check -s exit:0 rump.ifconfig shmif0 down 732 $DEBUG && rump.netstat -nr -f inet 733 $DEBUG && rump.arp -na 734 735 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 736 737 rump_server_destroy_ifaces 738 } 739 740 test_stray_entries() 741 { 742 743 rump_server_start $SOCKSRC 744 rump_server_start $SOCKDST 745 746 setup_dst_server 747 setup_src_server 748 749 rump_server_add_iface $SOCKSRC shmif1 bus1 750 751 export RUMP_SERVER=$SOCKSRC 752 atf_check -s exit:0 rump.ifconfig shmif1 inet $IP4SRC2/24 753 atf_check -s exit:0 rump.ifconfig -w 10 754 755 $DEBUG && rump.netstat -nr -f inet 756 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 757 $DEBUG && rump.arp -na 758 atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST 759 atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST 760 761 # Clean up 762 atf_check -s exit:0 -o ignore rump.arp -da 763 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 764 765 # ping from a different source address 766 atf_check -s exit:0 -o ignore \ 767 rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST 768 $DEBUG && rump.arp -na 769 atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST 770 # ARP reply goes back via shmif1, so a cache is created on shmif1 771 atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST 772 773 # Clean up by arp -da 774 atf_check -s exit:0 -o ignore rump.arp -da 775 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 776 777 # ping from a different source address again 778 atf_check -s exit:0 -o ignore \ 779 rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST 780 atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST 781 # ARP reply doen't come 782 atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST 783 784 # Cleanup caches on the destination 785 export RUMP_SERVER=$SOCKDST 786 atf_check -s exit:0 -o ignore rump.arp -da 787 export RUMP_SERVER=$SOCKSRC 788 789 # ping from a different source address again 790 atf_check -s exit:0 -o ignore \ 791 rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST 792 atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST 793 # ARP reply goes back via shmif1 794 atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST 795 796 # Clean up by arp -d <ip> 797 atf_check -s exit:0 -o ignore rump.arp -d $IP4DST 798 # Both entries should be deleted 799 atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST 800 801 rump_server_destroy_ifaces 802 } 803 804 test_cache_creation_common() 805 { 806 local no_dad=$1 807 808 rump_server_start $SOCKSRC 809 rump_server_start $SOCKDST 810 811 if $no_dad; then 812 export RUMP_SERVER=$SOCKSRC 813 atf_check -s exit:0 -o match:'3 -> 0' \ 814 rump.sysctl -w net.inet.ip.dad_count=0 815 export RUMP_SERVER=$SOCKDST 816 atf_check -s exit:0 -o match:'3 -> 0' \ 817 rump.sysctl -w net.inet.ip.dad_count=0 818 fi 819 820 setup_dst_server 821 setup_src_server 822 823 macaddr_src=$(get_macaddr $SOCKSRC shmif0) 824 macaddr_dst=$(get_macaddr $SOCKDST shmif0) 825 826 # ARP cache entries are not created for DAD/GARP packets. 827 export RUMP_SERVER=$SOCKSRC 828 atf_check -s exit:0 -o empty rump.arp -n -a 829 export RUMP_SERVER=$SOCKDST 830 atf_check -s exit:0 -o empty rump.arp -n -a 831 832 export RUMP_SERVER=$SOCKSRC 833 834 extract_new_packets bus1 > ./out 835 836 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST 837 $DEBUG && rump.arp -n -a 838 839 extract_new_packets bus1 > ./out 840 841 atf_check -s exit:0 -o match:"\? \(10.0.1.2\) at $macaddr_dst on shmif0 [0-9]+s R" \ 842 rump.arp -n -a 843 844 export RUMP_SERVER=$SOCKDST 845 846 # An entry was first created as stale then sending an ARP reply made it delay. 847 atf_check -s exit:0 -o match:"\? \(10.0.1.1\) at $macaddr_src on shmif0 [0-9]+s D" \ 848 rump.arp -n -a 849 850 # The sender resolves the receiver's address. 851 pkt=$(make_pkt_str_arpreq 10.0.1.2 10.0.1.1) 852 atf_check -s exit:0 -o match:"$pkt" cat ./out 853 854 # The receiver doesn't resolv the sender's address because the ARP request 855 # from the sender has let make an entry already. 856 pkt=$(make_pkt_str_arpreq 10.0.1.1 10.0.1.2) 857 atf_check -s exit:0 -o not-match:"$pkt" cat ./out 858 859 rump_server_destroy_ifaces 860 } 861 862 test_cache_creation() 863 { 864 865 test_cache_creation_common false 866 } 867 868 test_cache_creation_nodad() 869 { 870 871 test_cache_creation_common true 872 } 873 874 test_arp_request_count() 875 { 876 877 export RUMP_SERVER=$SOCKSRC 878 pkt=$(make_pkt_str_arpreq 10.0.1.2 10.0.1.1) 879 880 extract_new_packets bus1 > ./out 881 atf_check -s not-exit:0 -o ignore -e ignore rump.ping -n -c 1 $IP4DST 882 extract_new_packets bus1 > ./out 883 884 # ARP sends request packets net.inet.arp.nd_bmaxtries times at most. 885 times=$(rump.sysctl -n net.inet.arp.nd_bmaxtries) 886 $DEBUG && echo times=$times 887 $DEBUG && cat ./out 888 atf_check -s exit:0 -o match:"$pkt" cat ./out 889 atf_check -s exit:0 -o match:"$times" sh -c "grep -E '$pkt' ./out |wc -l" 890 } 891 892 test_resolution() 893 { 894 895 rump_server_start $SOCKSRC 896 setup_src_server 897 898 export RUMP_SERVER=$SOCKSRC 899 900 # Test default value of net.inet.arp.nd_bmaxtries 901 test_arp_request_count 902 903 # Test net.inet.arp.nd_bmaxtries=1 904 atf_check -s exit:0 rump.sysctl -wq net.inet.arp.nd_bmaxtries=1 905 test_arp_request_count 906 907 rump_server_destroy_ifaces 908 } 909 910 add_test() 911 { 912 local name=$1 913 local desc="$2" 914 915 atf_test_case "arp_${name}" cleanup 916 eval "arp_${name}_head() { 917 atf_set descr \"${desc}\" 918 atf_set require.progs rump_server 919 } 920 arp_${name}_body() { 921 test_${name} 922 } 923 arp_${name}_cleanup() { 924 \$DEBUG && dump 925 cleanup 926 }" 927 atf_add_test_case "arp_${name}" 928 } 929 930 atf_init_test_cases() 931 { 932 933 add_test cache_expiration "Tests for ARP cache expiration" 934 add_test command "Tests for arp_commands of arp(8)" 935 add_test garp "Tests for GARP" 936 add_test garp_without_dad "Tests for GARP with DAD disabled" 937 add_test cache_overwriting "Tests for behavior of overwriting ARP caches" 938 add_test proxy_arp_pub "Tests for Proxy ARP (pub)" 939 add_test proxy_arp_pubproxy "Tests for Proxy ARP (pub proxy)" 940 add_test link_activation "Tests for activating a new MAC address" 941 add_test static "Tests for static ARP entries" 942 add_test rtm "Tests for routing messages on operations of ARP entries" 943 add_test purge_on_route_change "Tests if ARP entries are removed on route change" 944 add_test purge_on_route_delete "Tests if ARP entries are removed on route delete" 945 add_test purge_on_ifdown "Tests if ARP entries are removed on interface down" 946 add_test stray_entries "Tests if ARP entries are removed on route change" 947 add_test cache_creation "Tests for ARP cache creation" 948 add_test cache_creation_nodad "Tests for ARP cache creation without DAD" 949 add_test resolution "Tests for ARP resolution" 950 } 951