Skip to content

Commit dbff47c

Browse files
committed
selftests: Add a basic HSR test.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2177256 Conflicts: - tools/testing/selftests/Makefile: context difference due to missing selftest targets commit 7d0455e Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Tue Nov 29 17:48:15 2022 +0100 selftests: Add a basic HSR test. This test adds a basic HSRv0 network with 3 nodes. In its current shape it sends and forwards packets, announcements and so merges nodes based on MAC A/B information. It is able to detect duplicate packets and packetloss should any occur. Cc: Shuah Khan <shuah@kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Felix Maurer <fmaurer@redhat.com>
1 parent fb59219 commit dbff47c

File tree

4 files changed

+268
-0
lines changed

4 files changed

+268
-0
lines changed

tools/testing/selftests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ TARGETS += mqueue
4343
TARGETS += nci
4444
TARGETS += net
4545
TARGETS += net/forwarding
46+
TARGETS += net/hsr
4647
TARGETS += net/mptcp
4748
TARGETS += netfilter
4849
TARGETS += nsfs
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
top_srcdir = ../../../../..
4+
5+
TEST_PROGS := hsr_ping.sh
6+
7+
include ../../lib.mk
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_IPV6=y
2+
CONFIG_NET_SCH_NETEM=m
3+
CONFIG_HSR=y
4+
CONFIG_VETH=y
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
ret=0
5+
ksft_skip=4
6+
ipv6=true
7+
8+
optstring="h4"
9+
usage() {
10+
echo "Usage: $0 [OPTION]"
11+
echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)"
12+
}
13+
14+
while 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+
;;
27+
esac
28+
done
29+
30+
sec=$(date +%s)
31+
rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
32+
ns1="ns1-$rndh"
33+
ns2="ns2-$rndh"
34+
ns3="ns3-$rndh"
35+
36+
cleanup()
37+
{
38+
local netns
39+
for netns in "$ns1" "$ns2" "$ns3" ;do
40+
ip netns del $netns
41+
done
42+
}
43+
44+
ip -Version > /dev/null 2>&1
45+
if [ $? -ne 0 ];then
46+
echo "SKIP: Could not run test without ip tool"
47+
exit $ksft_skip
48+
fi
49+
50+
trap cleanup EXIT
51+
52+
for i in "$ns1" "$ns2" "$ns3" ;do
53+
ip netns add $i || exit $ksft_skip
54+
ip -net $i link set lo up
55+
done
56+
57+
echo "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
69+
ip link add ns1eth1 netns "$ns1" type veth peer name ns2eth1 netns "$ns2"
70+
ip link add ns1eth2 netns "$ns1" type veth peer name ns3eth1 netns "$ns3"
71+
ip link add ns3eth2 netns "$ns3" type veth peer name ns2eth2 netns "$ns2"
72+
73+
# HSRv0.
74+
ip -net "$ns1" link add name hsr1 type hsr slave1 ns1eth1 slave2 ns1eth2 supervision 45 version 0 proto 0
75+
ip -net "$ns2" link add name hsr2 type hsr slave1 ns2eth1 slave2 ns2eth2 supervision 45 version 0 proto 0
76+
ip -net "$ns3" link add name hsr3 type hsr slave1 ns3eth1 slave2 ns3eth2 supervision 45 version 0 proto 0
77+
78+
# IP for HSR
79+
ip -net "$ns1" addr add 100.64.0.1/24 dev hsr1
80+
ip -net "$ns1" addr add dead:beef:1::1/64 dev hsr1 nodad
81+
ip -net "$ns2" addr add 100.64.0.2/24 dev hsr2
82+
ip -net "$ns2" addr add dead:beef:1::2/64 dev hsr2 nodad
83+
ip -net "$ns3" addr add 100.64.0.3/24 dev hsr3
84+
ip -net "$ns3" addr add dead:beef:1::3/64 dev hsr3 nodad
85+
86+
# All Links up
87+
ip -net "$ns1" link set ns1eth1 up
88+
ip -net "$ns1" link set ns1eth2 up
89+
ip -net "$ns1" link set hsr1 up
90+
91+
ip -net "$ns2" link set ns2eth1 up
92+
ip -net "$ns2" link set ns2eth2 up
93+
ip -net "$ns2" link set hsr2 up
94+
95+
ip -net "$ns3" link set ns3eth1 up
96+
ip -net "$ns3" link set ns3eth2 up
97+
ip -net "$ns3" link set hsr3 up
98+
99+
# $1: IP address
100+
is_v6()
101+
{
102+
[ -z "${1##*:*}" ]
103+
}
104+
105+
do_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+
126+
do_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+
157+
stop_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+
168+
echo "INFO: Initial validation ping."
169+
# Each node has to be able each one.
170+
do_ping "$ns1" 100.64.0.2
171+
do_ping "$ns2" 100.64.0.1
172+
do_ping "$ns3" 100.64.0.1
173+
stop_if_error "Initial validation failed."
174+
175+
do_ping "$ns1" 100.64.0.3
176+
do_ping "$ns2" 100.64.0.3
177+
do_ping "$ns3" 100.64.0.2
178+
179+
do_ping "$ns1" dead:beef:1::2
180+
do_ping "$ns1" dead:beef:1::3
181+
do_ping "$ns2" dead:beef:1::1
182+
do_ping "$ns2" dead:beef:1::2
183+
do_ping "$ns3" dead:beef:1::1
184+
do_ping "$ns3" dead:beef:1::2
185+
186+
stop_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.
191+
WAIT=5
192+
while [ ${WAIT} -gt 0 ]
193+
do
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
201+
done
202+
203+
# Just a safety delay in case the above check didn't handle it.
204+
sleep 1
205+
206+
echo "INFO: Longer ping test."
207+
do_ping_long "$ns1" 100.64.0.2
208+
do_ping_long "$ns1" dead:beef:1::2
209+
do_ping_long "$ns1" 100.64.0.3
210+
do_ping_long "$ns1" dead:beef:1::3
211+
212+
stop_if_error "Longer ping test failed."
213+
214+
do_ping_long "$ns2" 100.64.0.1
215+
do_ping_long "$ns2" dead:beef:1::1
216+
do_ping_long "$ns2" 100.64.0.3
217+
do_ping_long "$ns2" dead:beef:1::2
218+
stop_if_error "Longer ping test failed."
219+
220+
do_ping_long "$ns3" 100.64.0.1
221+
do_ping_long "$ns3" dead:beef:1::1
222+
do_ping_long "$ns3" 100.64.0.2
223+
do_ping_long "$ns3" dead:beef:1::2
224+
stop_if_error "Longer ping test failed."
225+
226+
echo "INFO: Cutting one link."
227+
do_ping_long "$ns1" 100.64.0.3 &
228+
229+
sleep 3
230+
ip -net "$ns3" link set ns3eth1 down
231+
wait
232+
233+
ip -net "$ns3" link set ns3eth1 up
234+
235+
stop_if_error "Failed with one link down."
236+
237+
echo "INFO: Delay the link and drop a few packages."
238+
tc -net "$ns3" qdisc add dev ns3eth1 root netem delay 50ms
239+
tc -net "$ns2" qdisc add dev ns2eth1 root netem delay 5ms loss 25%
240+
241+
do_ping_long "$ns1" 100.64.0.2
242+
do_ping_long "$ns1" 100.64.0.3
243+
244+
stop_if_error "Failed with delay and packetloss."
245+
246+
do_ping_long "$ns2" 100.64.0.1
247+
do_ping_long "$ns2" 100.64.0.3
248+
249+
stop_if_error "Failed with delay and packetloss."
250+
251+
do_ping_long "$ns3" 100.64.0.1
252+
do_ping_long "$ns3" 100.64.0.2
253+
stop_if_error "Failed with delay and packetloss."
254+
255+
echo "INFO: All good."
256+
exit $ret

0 commit comments

Comments
 (0)