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