1# $NetBSD: t_basic.sh,v 1.9 2023/09/19 11:55:14 gson Exp $ 2# 3# Copyright (c) 2017 Internet Initiative Japan 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 28SOCK_CLIENT=unix://carp_client 29SOCK_MASTER=unix://carp_master 30SOCK_BACKUP=unix://carp_backup 31BUS=bus_carp 32TIMEOUT=3 33 34DEBUG=${DEBUG:-false} 35 36IP_CLIENT=10.1.1.240 37IP_MASTER=10.1.1.1 38IP_BACKUP=10.1.1.2 39IP_CARP=10.1.1.100 40 41setup_carp() 42{ 43 local sock=$1 44 local master=$2 45 local carpdevip=$3 46 local carpif= ip= advskew= 47 48 if $master; then 49 carpif=carp0 50 ip=$IP_MASTER 51 advskew=0 52 else 53 carpif=carp1 54 ip=$IP_BACKUP 55 advskew=200 56 fi 57 58 export RUMP_SERVER=$sock 59 if $DEBUG; then 60 atf_check -s exit:0 -o match:'0.->.1' \ 61 rump.sysctl -w net.inet.carp.log=1 62 fi 63 rump_server_add_iface $sock $carpif 64 if [ $carpdevip = yes ]; then 65 atf_check -s exit:0 rump.ifconfig shmif0 $ip/24 up 66 atf_check -s exit:0 rump.ifconfig $carpif \ 67 vhid 175 advskew $advskew advbase 1 pass s3cret \ 68 $IP_CARP netmask 255.255.255.0 69 else 70 atf_check -s exit:0 rump.ifconfig shmif0 up 71 atf_check -s exit:0 rump.ifconfig $carpif \ 72 vhid 175 advskew $advskew advbase 1 pass s3cret \ 73 carpdev shmif0 $IP_CARP netmask 255.255.255.0 74 fi 75 atf_check -s exit:0 rump.ifconfig -w 10 76} 77 78wait_handover() 79{ 80 local i=0 81 82 export RUMP_SERVER=$SOCK_CLIENT 83 84 while [ $i -ne 5 ]; do 85 $DEBUG && echo "Trying ping $IP_CARP" 86 rump.ping -n -w 1 -c 1 $IP_CARP >/dev/null 87 if [ $? = 0 ]; then 88 $DEBUG && echo "Passed ping $IP_CARP" 89 break; 90 fi 91 $DEBUG && echo "Failed ping $IP_CARP" 92 i=$((i + 1)) 93 done 94 95 if [ $i -eq 5 ]; then 96 atf_fail "Failed to failover (5 sec)" 97 fi 98} 99 100test_carp_handover_ipv4() 101{ 102 local op=$1 103 local carpdevip=$2 104 105 rump_server_start $SOCK_CLIENT 106 rump_server_start $SOCK_MASTER 107 rump_server_start $SOCK_BACKUP 108 109 rump_server_add_iface $SOCK_CLIENT shmif0 $BUS 110 rump_server_add_iface $SOCK_MASTER shmif0 $BUS 111 rump_server_add_iface $SOCK_BACKUP shmif0 $BUS 112 113 setup_carp $SOCK_MASTER true $carpdevip 114 setup_carp $SOCK_BACKUP false $carpdevip 115 116 export RUMP_SERVER=$SOCK_CLIENT 117 atf_check -s exit:0 rump.ifconfig shmif0 $IP_CLIENT/24 up 118 atf_check -s exit:0 rump.ifconfig -w 10 119 120 if [ $carpdevip = yes ]; then 121 # Check that the primary addresses are up 122 atf_check -s exit:0 -o ignore \ 123 rump.ping -n -w $TIMEOUT -c 1 $IP_MASTER 124 atf_check -s exit:0 -o ignore \ 125 rump.ping -n -w $TIMEOUT -c 1 $IP_BACKUP 126 fi 127 128 # Give carp a while to croak 129 sleep 4 130 131 # Check state 132 export RUMP_SERVER=$SOCK_MASTER 133 $DEBUG && rump.ifconfig 134 atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ 135 rump.ifconfig carp0 136 export RUMP_SERVER=$SOCK_BACKUP 137 $DEBUG && rump.ifconfig 138 atf_check -s exit:0 -o match:'carp: BACKUP carpdev shmif0' \ 139 rump.ifconfig carp1 140 export RUMP_SERVER=$SOCK_CLIENT 141 142 # Check that the shared IP works 143 atf_check -s exit:0 -o ignore \ 144 rump.ping -n -w $TIMEOUT -c 1 $IP_CARP 145 146 # KILLING SPREE 147 if [ $op = halt ]; then 148 env RUMP_SERVER=$SOCK_MASTER rump.halt 149 elif [ $op = ifdown ]; then 150 env RUMP_SERVER=$SOCK_MASTER rump.ifconfig shmif0 down 151 fi 152 sleep 1 153 154 # Check that primary is now dead 155 if [ $carpdevip = yes ]; then 156 atf_check -s not-exit:0 -o ignore \ 157 rump.ping -n -w $TIMEOUT -c 1 $IP_MASTER 158 else 159 # XXX how to check? 160 fi 161 162 # Do it in installments. carp will cluck meanwhile 163 wait_handover 164 165 # Check state 166 export RUMP_SERVER=$SOCK_BACKUP 167 $DEBUG && rump.ifconfig 168 atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ 169 rump.ifconfig carp1 170 171 if [ $op = ifdown ]; then 172 rump_server_destroy_ifaces 173 fi 174} 175 176IP6_CLIENT=fd00:1::240 177IP6_MASTER=fd00:1::1 178IP6_BACKUP=fd00:1::2 179IP6_CARP=fd00:1::100 180 181setup_carp6() 182{ 183 local sock=$1 184 local master=$2 185 local carpdevip=$3 186 local carpif= ip= advskew= 187 188 if $master; then 189 carpif=carp0 190 ip=$IP6_MASTER 191 advskew=0 192 else 193 carpif=carp1 194 ip=$IP6_BACKUP 195 advskew=200 196 fi 197 198 export RUMP_SERVER=$sock 199 if $DEBUG; then 200 atf_check -s exit:0 -o match:'0.->.1' \ 201 rump.sysctl -w net.inet.carp.log=1 202 fi 203 rump_server_add_iface $sock $carpif 204 if [ $carpdevip = yes ]; then 205 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip up 206 atf_check -s exit:0 rump.ifconfig $carpif inet6 \ 207 vhid 175 advskew $advskew advbase 1 pass s3cret $IP6_CARP 208 else 209 atf_check -s exit:0 rump.ifconfig shmif0 up 210 atf_check -s exit:0 rump.ifconfig $carpif inet6 \ 211 vhid 175 advskew $advskew advbase 1 pass s3cret \ 212 carpdev shmif0 $IP6_CARP 213 fi 214 atf_check -s exit:0 rump.ifconfig -w 10 215} 216 217wait_carp6_handover() 218{ 219 local i=0 220 221 export RUMP_SERVER=$SOCK_CLIENT 222 223 while [ $i -ne 5 ]; do 224 $DEBUG && echo "Trying ping6 $IP6_CARP" 225 rump.ping6 -n -X 1 -c 1 $IP6_CARP >/dev/null 226 if [ $? = 0 ]; then 227 $DEBUG && echo "Passed ping $IP6_CARP" 228 break; 229 fi 230 $DEBUG && echo "Failed ping6 $IP6_CARP" 231 i=$((i + 1)) 232 done 233 234 if [ $i -eq 5 ]; then 235 atf_fail "Failed to failover (5 sec)" 236 fi 237} 238 239test_carp_handover_ipv6() 240{ 241 local op=$1 242 local carpdevip=$2 243 244 rump_server_start $SOCK_CLIENT netinet6 245 rump_server_start $SOCK_MASTER netinet6 246 rump_server_start $SOCK_BACKUP netinet6 247 248 rump_server_add_iface $SOCK_CLIENT shmif0 $BUS 249 rump_server_add_iface $SOCK_MASTER shmif0 $BUS 250 rump_server_add_iface $SOCK_BACKUP shmif0 $BUS 251 252 setup_carp6 $SOCK_MASTER true $carpdevip 253 setup_carp6 $SOCK_BACKUP false $carpdevip 254 255 export RUMP_SERVER=$SOCK_CLIENT 256 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_CLIENT up 257 atf_check -s exit:0 rump.ifconfig -w 10 258 259 if [ $carpdevip = yes ]; then 260 # Check that the primary addresses are up 261 atf_check -s exit:0 -o ignore \ 262 rump.ping6 -n -X $TIMEOUT -c 1 $IP6_MASTER 263 atf_check -s exit:0 -o ignore \ 264 rump.ping6 -n -X $TIMEOUT -c 1 $IP6_BACKUP 265 fi 266 267 # Give carp a while to croak 268 sleep 4 269 270 # Check state 271 export RUMP_SERVER=$SOCK_MASTER 272 $DEBUG && rump.ifconfig 273 atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ 274 rump.ifconfig carp0 275 export RUMP_SERVER=$SOCK_BACKUP 276 $DEBUG && rump.ifconfig 277 atf_check -s exit:0 -o match:'carp: BACKUP carpdev shmif0' \ 278 rump.ifconfig carp1 279 export RUMP_SERVER=$SOCK_CLIENT 280 281 # Check that the shared IP works 282 atf_check -s exit:0 -o ignore \ 283 rump.ping6 -n -X $TIMEOUT -c 1 $IP6_CARP 284 285 # KILLING SPREE 286 if [ $op = halt ]; then 287 env RUMP_SERVER=$SOCK_MASTER rump.halt 288 elif [ $op = ifdown ]; then 289 env RUMP_SERVER=$SOCK_MASTER rump.ifconfig shmif0 down 290 fi 291 sleep 1 292 293 # Check that primary is now dead 294 if [ $carpdevip = yes ]; then 295 atf_check -s not-exit:0 -o ignore \ 296 rump.ping6 -n -X $TIMEOUT -c 1 $IP6_MASTER 297 else 298 # XXX how to check? 299 fi 300 301 # Do it in installments. carp will cluck meanwhile 302 wait_carp6_handover 303 304 # Check state 305 export RUMP_SERVER=$SOCK_BACKUP 306 $DEBUG && rump.ifconfig 307 atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ 308 rump.ifconfig carp1 309 310 if [ $op = ifdown ]; then 311 rump_server_destroy_ifaces 312 fi 313} 314 315add_test_case() 316{ 317 local ipproto=$1 318 local halt=$2 319 local carpdevip=$3 320 local expected_failure_code= 321 322 name="carp_handover_${ipproto}_${halt}" 323 desc="Tests for CARP (${ipproto}) handover on ${halt}" 324 if [ $carpdevip = yes ]; then 325 name="${name}_carpdevip" 326 desc="$desc with carpdev IP" 327 else 328 name="${name}_nocarpdevip" 329 desc="$desc without carpdev IP" 330 fi 331 332 atf_test_case ${name} cleanup 333 eval " 334 ${name}_head() { 335 atf_set descr \"$desc\" 336 atf_set require.progs rump_server 337 } 338 ${name}_body() { 339 $expected_failure_code 340 test_carp_handover_${ipproto} $halt $carpdevip 341 if [ $halt != halt ]; then 342 rump_server_destroy_ifaces 343 fi 344 } 345 ${name}_cleanup() { 346 \$DEBUG && dump 347 cleanup 348 } 349 " 350 atf_add_test_case ${name} 351} 352 353atf_init_test_cases() 354{ 355 local proto= halt= carpdevip= 356 357 for proto in ipv4 ipv6; do 358 for halt in halt ifdown; do 359 for carpdevip in yes no; do 360 add_test_case $proto $halt $carpdevip 361 done 362 done 363 done 364} 365