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