Home | History | Annotate | Line # | Download | only in carp
      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 
     28 SOCK_CLIENT=unix://carp_client
     29 SOCK_MASTER=unix://carp_master
     30 SOCK_BACKUP=unix://carp_backup
     31 BUS=bus_carp
     32 TIMEOUT=3
     33 
     34 DEBUG=${DEBUG:-false}
     35 
     36 IP_CLIENT=10.1.1.240
     37 IP_MASTER=10.1.1.1
     38 IP_BACKUP=10.1.1.2
     39 IP_CARP=10.1.1.100
     40 
     41 setup_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 
     78 wait_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 
    100 test_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 
    176 IP6_CLIENT=fd00:1::240
    177 IP6_MASTER=fd00:1::1
    178 IP6_BACKUP=fd00:1::2
    179 IP6_CARP=fd00:1::100
    180 
    181 setup_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 
    217 wait_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 
    239 test_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 
    315 add_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 
    353 atf_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