1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ret=0 5ksft_skip=4 6ipv6=true 7 8optstring="h4" 9usage() { 10 echo "Usage: $0 [OPTION]" 11 echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)" 12} 13 14while getopts "$optstring" option;do 15 case "$option" in 16 "h") 17 usage $0 18 exit 0 19 ;; 20 "4") 21 ipv6=false 22 ;; 23 "?") 24 usage $0 25 exit 1 26 ;; 27esac 28done 29 30sec=$(date +%s) 31rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 32ns1="ns1-$rndh" 33ns2="ns2-$rndh" 34ns3="ns3-$rndh" 35 36cleanup() 37{ 38 local netns 39 for netns in "$ns1" "$ns2" "$ns3" ;do 40 ip netns del $netns 41 done 42} 43 44# $1: IP address 45is_v6() 46{ 47 [ -z "${1##*:*}" ] 48} 49 50do_ping() 51{ 52 local netns="$1" 53 local connect_addr="$2" 54 local ping_args="-q -c 2" 55 56 if is_v6 "${connect_addr}"; then 57 $ipv6 || return 0 58 ping_args="${ping_args} -6" 59 fi 60 61 ip netns exec ${netns} ping ${ping_args} $connect_addr >/dev/null 62 if [ $? -ne 0 ] ; then 63 echo "$netns -> $connect_addr connectivity [ FAIL ]" 1>&2 64 ret=1 65 return 1 66 fi 67 68 return 0 69} 70 71do_ping_long() 72{ 73 local netns="$1" 74 local connect_addr="$2" 75 local ping_args="-q -c 10" 76 77 if is_v6 "${connect_addr}"; then 78 $ipv6 || return 0 79 ping_args="${ping_args} -6" 80 fi 81 82 OUT="$(LANG=C ip netns exec ${netns} ping ${ping_args} $connect_addr | grep received)" 83 if [ $? -ne 0 ] ; then 84 echo "$netns -> $connect_addr ping [ FAIL ]" 1>&2 85 ret=1 86 return 1 87 fi 88 89 VAL="$(echo $OUT | cut -d' ' -f1-8)" 90 if [ "$VAL" != "10 packets transmitted, 10 received, 0% packet loss," ] 91 then 92 echo "$netns -> $connect_addr ping TEST [ FAIL ]" 93 echo "Expect to send and receive 10 packets and no duplicates." 94 echo "Full message: ${OUT}." 95 ret=1 96 return 1 97 fi 98 99 return 0 100} 101 102stop_if_error() 103{ 104 local msg="$1" 105 106 if [ ${ret} -ne 0 ]; then 107 echo "FAIL: ${msg}" 1>&2 108 exit ${ret} 109 fi 110} 111 112do_complete_ping_test() 113{ 114 echo "INFO: Initial validation ping." 115 # Each node has to be able each one. 116 do_ping "$ns1" 100.64.0.2 117 do_ping "$ns2" 100.64.0.1 118 do_ping "$ns3" 100.64.0.1 119 stop_if_error "Initial validation failed." 120 121 do_ping "$ns1" 100.64.0.3 122 do_ping "$ns2" 100.64.0.3 123 do_ping "$ns3" 100.64.0.2 124 125 do_ping "$ns1" dead:beef:1::2 126 do_ping "$ns1" dead:beef:1::3 127 do_ping "$ns2" dead:beef:1::1 128 do_ping "$ns2" dead:beef:1::2 129 do_ping "$ns3" dead:beef:1::1 130 do_ping "$ns3" dead:beef:1::2 131 132 stop_if_error "Initial validation failed." 133 134# Wait until supervisor all supervision frames have been processed and the node 135# entries have been merged. Otherwise duplicate frames will be observed which is 136# valid at this stage. 137 WAIT=5 138 while [ ${WAIT} -gt 0 ] 139 do 140 grep 00:00:00:00:00:00 /sys/kernel/debug/hsr/hsr*/node_table 141 if [ $? -ne 0 ] 142 then 143 break 144 fi 145 sleep 1 146 let "WAIT = WAIT - 1" 147 done 148 149# Just a safety delay in case the above check didn't handle it. 150 sleep 1 151 152 echo "INFO: Longer ping test." 153 do_ping_long "$ns1" 100.64.0.2 154 do_ping_long "$ns1" dead:beef:1::2 155 do_ping_long "$ns1" 100.64.0.3 156 do_ping_long "$ns1" dead:beef:1::3 157 158 stop_if_error "Longer ping test failed." 159 160 do_ping_long "$ns2" 100.64.0.1 161 do_ping_long "$ns2" dead:beef:1::1 162 do_ping_long "$ns2" 100.64.0.3 163 do_ping_long "$ns2" dead:beef:1::2 164 stop_if_error "Longer ping test failed." 165 166 do_ping_long "$ns3" 100.64.0.1 167 do_ping_long "$ns3" dead:beef:1::1 168 do_ping_long "$ns3" 100.64.0.2 169 do_ping_long "$ns3" dead:beef:1::2 170 stop_if_error "Longer ping test failed." 171 172 echo "INFO: Cutting one link." 173 do_ping_long "$ns1" 100.64.0.3 & 174 175 sleep 3 176 ip -net "$ns3" link set ns3eth1 down 177 wait 178 179 ip -net "$ns3" link set ns3eth1 up 180 181 stop_if_error "Failed with one link down." 182 183 echo "INFO: Delay the link and drop a few packages." 184 tc -net "$ns3" qdisc add dev ns3eth1 root netem delay 50ms 185 tc -net "$ns2" qdisc add dev ns2eth1 root netem delay 5ms loss 25% 186 187 do_ping_long "$ns1" 100.64.0.2 188 do_ping_long "$ns1" 100.64.0.3 189 190 stop_if_error "Failed with delay and packetloss." 191 192 do_ping_long "$ns2" 100.64.0.1 193 do_ping_long "$ns2" 100.64.0.3 194 195 stop_if_error "Failed with delay and packetloss." 196 197 do_ping_long "$ns3" 100.64.0.1 198 do_ping_long "$ns3" 100.64.0.2 199 stop_if_error "Failed with delay and packetloss." 200 201 echo "INFO: All good." 202} 203 204setup_hsr_interfaces() 205{ 206 local HSRv="$1" 207 208 echo "INFO: preparing interfaces for HSRv${HSRv}." 209# Three HSR nodes. Each node has one link to each of its neighbour, two links in total. 210# 211# ns1eth1 ----- ns2eth1 212# hsr1 hsr2 213# ns1eth2 ns2eth2 214# | | 215# ns3eth1 ns3eth2 216# \ / 217# hsr3 218# 219 # Interfaces 220 ip link add ns1eth1 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 221 ip link add ns1eth2 netns "$ns1" type veth peer name ns3eth1 netns "$ns3" 222 ip link add ns3eth2 netns "$ns3" type veth peer name ns2eth2 netns "$ns2" 223 224 # HSRv0/1 225 ip -net "$ns1" link add name hsr1 type hsr slave1 ns1eth1 slave2 ns1eth2 supervision 45 version $HSRv proto 0 226 ip -net "$ns2" link add name hsr2 type hsr slave1 ns2eth1 slave2 ns2eth2 supervision 45 version $HSRv proto 0 227 ip -net "$ns3" link add name hsr3 type hsr slave1 ns3eth1 slave2 ns3eth2 supervision 45 version $HSRv proto 0 228 229 # IP for HSR 230 ip -net "$ns1" addr add 100.64.0.1/24 dev hsr1 231 ip -net "$ns1" addr add dead:beef:1::1/64 dev hsr1 nodad 232 ip -net "$ns2" addr add 100.64.0.2/24 dev hsr2 233 ip -net "$ns2" addr add dead:beef:1::2/64 dev hsr2 nodad 234 ip -net "$ns3" addr add 100.64.0.3/24 dev hsr3 235 ip -net "$ns3" addr add dead:beef:1::3/64 dev hsr3 nodad 236 237 # All Links up 238 ip -net "$ns1" link set ns1eth1 up 239 ip -net "$ns1" link set ns1eth2 up 240 ip -net "$ns1" link set hsr1 up 241 242 ip -net "$ns2" link set ns2eth1 up 243 ip -net "$ns2" link set ns2eth2 up 244 ip -net "$ns2" link set hsr2 up 245 246 ip -net "$ns3" link set ns3eth1 up 247 ip -net "$ns3" link set ns3eth2 up 248 ip -net "$ns3" link set hsr3 up 249} 250 251ip -Version > /dev/null 2>&1 252if [ $? -ne 0 ];then 253 echo "SKIP: Could not run test without ip tool" 254 exit $ksft_skip 255fi 256 257trap cleanup EXIT 258 259for i in "$ns1" "$ns2" "$ns3" ;do 260 ip netns add $i || exit $ksft_skip 261 ip -net $i link set lo up 262done 263 264setup_hsr_interfaces 0 265do_complete_ping_test 266cleanup 267 268for i in "$ns1" "$ns2" "$ns3" ;do 269 ip netns add $i || exit $ksft_skip 270 ip -net $i link set lo up 271done 272 273setup_hsr_interfaces 1 274do_complete_ping_test 275 276exit $ret 277