1# $FreeBSD$ 2# 3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4# 5# Copyright (c) 2020 Kristof Provost <kp@FreeBSD.org> 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27 28. $(atf_get_srcdir)/../common/vnet.subr 29 30is_master() 31{ 32 jail=$1 33 itf=$2 34 35 jexec ${jail} ifconfig ${itf} | grep carp | grep MASTER 36} 37 38wait_for_carp() 39{ 40 jail1=$1 41 itf1=$2 42 jail2=$3 43 itf2=$4 44 45 while [ -z "$(is_master ${jail1} ${itf1})" ] && 46 [ -z "$(is_master ${jail2} ${itf2})" ]; do 47 sleep 1 48 done 49 50 if [ -n "$(is_master ${jail1} ${itf1})" ] && 51 [ -n "$(is_master ${jail2} ${itf2})" ]; then 52 atf_fail "Both jails are master" 53 fi 54} 55 56carp_init() 57{ 58 if ! kldstat -q -m carp; then 59 atf_skip "This test requires carp" 60 fi 61 62 vnet_init 63} 64 65atf_test_case "basic_v4" "cleanup" 66basic_v4_head() 67{ 68 atf_set descr 'Basic CARP test (IPv4)' 69 atf_set require.user root 70} 71 72basic_v4_body() 73{ 74 carp_init 75 76 bridge=$(vnet_mkbridge) 77 epair_one=$(vnet_mkepair) 78 epair_two=$(vnet_mkepair) 79 80 vnet_mkjail carp_basic_v4_one ${bridge} ${epair_one}a ${epair_two}a 81 vnet_mkjail carp_basic_v4_two ${epair_one}b 82 vnet_mkjail carp_basic_v4_three ${epair_two}b 83 84 jexec carp_basic_v4_one ifconfig ${bridge} 192.0.2.4/29 up 85 jexec carp_basic_v4_one ifconfig ${bridge} addm ${epair_one}a \ 86 addm ${epair_two}a 87 jexec carp_basic_v4_one ifconfig ${epair_one}a up 88 jexec carp_basic_v4_one ifconfig ${epair_two}a up 89 90 jexec carp_basic_v4_two ifconfig ${epair_one}b 192.0.2.202/29 up 91 jexec carp_basic_v4_two ifconfig ${epair_one}b add vhid 1 192.0.2.1/29 92 93 jexec carp_basic_v4_three ifconfig ${epair_two}b 192.0.2.203/29 up 94 jexec carp_basic_v4_three ifconfig ${epair_two}b add vhid 1 \ 95 192.0.2.1/29 96 97 wait_for_carp carp_basic_v4_two ${epair_one}b \ 98 carp_basic_v4_three ${epair_two}b 99 100 atf_check -s exit:0 -o ignore jexec carp_basic_v4_one \ 101 ping -c 3 192.0.2.1 102} 103 104basic_v4_cleanup() 105{ 106 vnet_cleanup 107} 108 109atf_test_case "basic_v6" "cleanup" 110basic_v6_head() 111{ 112 atf_set descr 'Basic CARP test (IPv6)' 113 atf_set require.user root 114} 115 116basic_v6_body() 117{ 118 carp_init 119 120 bridge=$(vnet_mkbridge) 121 epair_one=$(vnet_mkepair) 122 epair_two=$(vnet_mkepair) 123 124 vnet_mkjail carp_basic_v6_one ${bridge} ${epair_one}a ${epair_two}a 125 vnet_mkjail carp_basic_v6_two ${epair_one}b 126 vnet_mkjail carp_basic_v6_three ${epair_two}b 127 128 jexec carp_basic_v6_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ 129 no_dad 130 jexec carp_basic_v6_one ifconfig ${bridge} addm ${epair_one}a \ 131 addm ${epair_two}a 132 jexec carp_basic_v6_one ifconfig ${epair_one}a up 133 jexec carp_basic_v6_one ifconfig ${epair_two}a up 134 135 jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 \ 136 2001:db8::1:2/64 up no_dad 137 jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 add vhid 1 \ 138 2001:db8::0:1/64 139 140 jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 2001:db8::1:3/64 up no_dad 141 jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 add vhid 1 \ 142 2001:db8::0:1/64 143 144 wait_for_carp carp_basic_v6_two ${epair_one}b \ 145 carp_basic_v6_three ${epair_two}b 146 147 atf_check -s exit:0 -o ignore jexec carp_basic_v6_one \ 148 ping -6 -c 3 2001:db8::0:1 149} 150 151basic_v6_cleanup() 152{ 153 vnet_cleanup 154} 155 156atf_test_case "negative_demotion" "cleanup" 157negative_demotion_head() 158{ 159 atf_set descr 'Test PR #259528' 160 atf_set require.user root 161} 162 163negative_demotion_body() 164{ 165 carp_init 166 167 epair=$(vnet_mkepair) 168 169 vnet_mkjail one ${epair}a 170 jexec one sysctl net.inet.carp.preempt=1 171 jexec one ifconfig ${epair}a 192.0.2.1/24 up 172 jexec one ifconfig ${epair}a add vhid 1 192.0.2.254/24 \ 173 advskew 0 pass foobar 174 175 vnet_mkjail two ${epair}b 176 jexec two sysctl net.inet.carp.preempt=1 177 jexec two ifconfig ${epair}b 192.0.2.2/24 up 178 jexec two ifconfig ${epair}b add vhid 1 192.0.2.254/24 \ 179 advskew 100 pass foobar 180 181 # Allow things to settle 182 wait_for_carp one ${epair}a two ${epair}b 183 184 if is_master one ${epair}a && is_master two ${epair}b 185 then 186 atf_fail "Two masters!" 187 fi 188 189 jexec one sysctl net.inet.carp.demotion=-1 190 sleep 3 191 192 if is_master one ${epair}a && is_master two ${epair}b 193 then 194 atf_fail "Two masters!" 195 fi 196} 197 198negative_demotion_cleanup() 199{ 200 vnet_cleanup 201} 202 203 204 205atf_test_case "nd6_ns_source_mac" "cleanup" 206nd6_ns_source_mac_head() 207{ 208 atf_set descr 'CARP ndp neighbor solicitation MAC source test (IPv6)' 209 atf_set require.user root 210} 211 212nd6_ns_source_mac_body() 213{ 214 carp_init 215 216 bridge=$(vnet_mkbridge) 217 epair_one=$(vnet_mkepair) 218 epair_two=$(vnet_mkepair) 219 220 vnet_mkjail carp_ndp_v6_bridge ${bridge} ${epair_one}a ${epair_two}a 221 vnet_mkjail carp_ndp_v6_master ${epair_one}b 222 vnet_mkjail carp_ndp_v6_slave ${epair_two}b 223 224 jexec carp_ndp_v6_bridge ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ 225 no_dad 226 jexec carp_ndp_v6_bridge ifconfig ${bridge} addm ${epair_one}a \ 227 addm ${epair_two}a 228 jexec carp_ndp_v6_bridge ifconfig ${epair_one}a up 229 jexec carp_ndp_v6_bridge ifconfig ${epair_two}a up 230 231 jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 \ 232 2001:db8::1:2/64 up no_dad 233 jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 add vhid 1 \ 234 advskew 0 2001:db8::0:1/64 235 236 jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 \ 237 2001:db8::1:3/64 up no_dad 238 jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 add vhid 1 \ 239 advskew 100 2001:db8::0:1/64 240 241 wait_for_carp carp_ndp_v6_master ${epair_one}b \ 242 carp_ndp_v6_slave ${epair_two}b 243 244 # carp_ndp_v6_master is MASTER 245 246 # trigger a NS from the virtual IP from the BACKUP 247 atf_check -s exit:2 -o ignore jexec carp_ndp_v6_slave \ 248 ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4 249 250 # trigger a NS from the virtual IP from the MASTER, 251 # this ping should work 252 atf_check -s exit:0 -o ignore jexec carp_ndp_v6_master \ 253 ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4 254 255 # ndp entry should be for the virtual mac 256 atf_check -o match:'2001:db8::1 +00:00:5e:00:01:01' \ 257 jexec carp_ndp_v6_bridge ndp -an 258} 259 260nd6_ns_source_mac_cleanup() 261{ 262 vnet_cleanup 263} 264 265 266atf_init_test_cases() 267{ 268 atf_add_test_case "basic_v4" 269 atf_add_test_case "basic_v6" 270 atf_add_test_case "negative_demotion" 271 atf_add_test_case "nd6_ns_source_mac" 272} 273