Skip to content

Commit ca4a09a

Browse files
fmaurer-rhPaolo Abeni
authored andcommitted
selftests: hsr: Add tests for faulty links
Add a test case that can support different types of faulty links for all protocol versions (HSRv0, HSRv1, PRPv1). It starts with a baseline with fully functional links. The first faulty case is one link being cut during the ping. This test uses a different function for ping that sends more packets in shorter intervals to stress the duplicate detection algorithms a bit more and allow for future tests with other link faults (packet loss, reordering, etc.). As the link fault tests now cover the cut link for HSR and PRP, it can be removed from the hsr_ping test. Note that the removed cut link test did not really test the fault because do_ping_long takes about 1sec while the link is only cut after a 3sec sleep. Signed-off-by: Felix Maurer <fmaurer@redhat.com> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/dad52276e2c349ecb96168bef7e3001bf7becc81.1770299429.git.fmaurer@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 776b64b commit ca4a09a

3 files changed

Lines changed: 272 additions & 11 deletions

File tree

tools/testing/selftests/net/hsr/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ top_srcdir = ../../../../..
55
TEST_PROGS := \
66
hsr_ping.sh \
77
hsr_redbox.sh \
8+
link_faults.sh \
89
prp_ping.sh \
910
# end of TEST_PROGS
1011

tools/testing/selftests/net/hsr/hsr_ping.sh

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,6 @@ do_link_problem_tests()
9494
{
9595
echo "INFO: Running link problem tests."
9696

97-
echo "INFO: Cutting one link."
98-
do_ping_long "$ns1" 100.64.0.3 &
99-
100-
sleep 3
101-
ip -net "$ns3" link set ns3eth1 down
102-
wait
103-
104-
ip -net "$ns3" link set ns3eth1 up
105-
106-
stop_if_error "Failed with one link down."
107-
10897
echo "INFO: Delay the link and drop a few packages."
10998
tc -net "$ns3" qdisc add dev ns3eth1 root netem delay 50ms
11099
tc -net "$ns2" qdisc add dev ns2eth1 root netem delay 5ms loss 25%
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
# shellcheck disable=SC2329
4+
5+
source ../lib.sh
6+
7+
ALL_TESTS="
8+
test_clean_hsrv0
9+
test_cut_link_hsrv0
10+
test_clean_hsrv1
11+
test_cut_link_hsrv1
12+
test_clean_prp
13+
test_cut_link_prp
14+
"
15+
16+
# The tests are running ping for 5sec with a relatively short interval with a
17+
# cut link, which should be recoverable by HSR/PRP.
18+
19+
setup_hsr_topo()
20+
{
21+
# Three HSR nodes in a ring, every node has a LAN A interface connected
22+
# to the LAN B interface of the next node.
23+
#
24+
# node1 node2
25+
#
26+
# vethA -------- vethB
27+
# hsr1 hsr2
28+
# vethB vethA
29+
# \ /
30+
# vethA vethB
31+
# hsr3
32+
#
33+
# node3
34+
35+
local ver="$1"
36+
37+
setup_ns node1 node2 node3
38+
39+
# veth links
40+
# shellcheck disable=SC2154 # variables assigned by setup_ns
41+
ip link add vethA netns "$node1" type veth peer name vethB netns "$node2"
42+
# shellcheck disable=SC2154 # variables assigned by setup_ns
43+
ip link add vethA netns "$node2" type veth peer name vethB netns "$node3"
44+
ip link add vethA netns "$node3" type veth peer name vethB netns "$node1"
45+
46+
# MAC addresses (not needed for HSR operation, but helps with debugging)
47+
ip -net "$node1" link set address 00:11:22:00:01:01 dev vethA
48+
ip -net "$node1" link set address 00:11:22:00:01:02 dev vethB
49+
50+
ip -net "$node2" link set address 00:11:22:00:02:01 dev vethA
51+
ip -net "$node2" link set address 00:11:22:00:02:02 dev vethB
52+
53+
ip -net "$node3" link set address 00:11:22:00:03:01 dev vethA
54+
ip -net "$node3" link set address 00:11:22:00:03:02 dev vethB
55+
56+
# HSR interfaces
57+
ip -net "$node1" link add name hsr1 type hsr proto 0 version "$ver" \
58+
slave1 vethA slave2 vethB supervision 45
59+
ip -net "$node2" link add name hsr2 type hsr proto 0 version "$ver" \
60+
slave1 vethA slave2 vethB supervision 45
61+
ip -net "$node3" link add name hsr3 type hsr proto 0 version "$ver" \
62+
slave1 vethA slave2 vethB supervision 45
63+
64+
# IP addresses
65+
ip -net "$node1" addr add 100.64.0.1/24 dev hsr1
66+
ip -net "$node2" addr add 100.64.0.2/24 dev hsr2
67+
ip -net "$node3" addr add 100.64.0.3/24 dev hsr3
68+
69+
# Set all links up
70+
ip -net "$node1" link set vethA up
71+
ip -net "$node1" link set vethB up
72+
ip -net "$node1" link set hsr1 up
73+
74+
ip -net "$node2" link set vethA up
75+
ip -net "$node2" link set vethB up
76+
ip -net "$node2" link set hsr2 up
77+
78+
ip -net "$node3" link set vethA up
79+
ip -net "$node3" link set vethB up
80+
ip -net "$node3" link set hsr3 up
81+
}
82+
83+
setup_prp_topo()
84+
{
85+
# Two PRP nodes, connected by two links (treated as LAN A and LAN B).
86+
#
87+
# vethA ----- vethA
88+
# prp1 prp2
89+
# vethB ----- vethB
90+
#
91+
# node1 node2
92+
93+
setup_ns node1 node2
94+
95+
# veth links
96+
ip link add vethA netns "$node1" type veth peer name vethA netns "$node2"
97+
ip link add vethB netns "$node1" type veth peer name vethB netns "$node2"
98+
99+
# MAC addresses will be copied from LAN A interface
100+
ip -net "$node1" link set address 00:11:22:00:00:01 dev vethA
101+
ip -net "$node2" link set address 00:11:22:00:00:02 dev vethA
102+
103+
# PRP interfaces
104+
ip -net "$node1" link add name prp1 type hsr \
105+
slave1 vethA slave2 vethB supervision 45 proto 1
106+
ip -net "$node2" link add name prp2 type hsr \
107+
slave1 vethA slave2 vethB supervision 45 proto 1
108+
109+
# IP addresses
110+
ip -net "$node1" addr add 100.64.0.1/24 dev prp1
111+
ip -net "$node2" addr add 100.64.0.2/24 dev prp2
112+
113+
# All links up
114+
ip -net "$node1" link set vethA up
115+
ip -net "$node1" link set vethB up
116+
ip -net "$node1" link set prp1 up
117+
118+
ip -net "$node2" link set vethA up
119+
ip -net "$node2" link set vethB up
120+
ip -net "$node2" link set prp2 up
121+
}
122+
123+
wait_for_hsr_node_table()
124+
{
125+
log_info "Wait for node table entries to be merged."
126+
WAIT=5
127+
while [ "${WAIT}" -gt 0 ]; do
128+
nts=$(cat /sys/kernel/debug/hsr/hsr*/node_table)
129+
130+
# We need entries in the node tables, and they need to be merged
131+
if (echo "$nts" | grep -qE "^([0-9a-f]{2}:){5}") && \
132+
! (echo "$nts" | grep -q "00:00:00:00:00:00"); then
133+
return
134+
fi
135+
136+
sleep 1
137+
((WAIT--))
138+
done
139+
check_err 1 "Failed to wait for merged node table entries"
140+
}
141+
142+
setup_topo()
143+
{
144+
local proto="$1"
145+
146+
if [ "$proto" = "HSRv0" ]; then
147+
setup_hsr_topo 0
148+
wait_for_hsr_node_table
149+
elif [ "$proto" = "HSRv1" ]; then
150+
setup_hsr_topo 1
151+
wait_for_hsr_node_table
152+
elif [ "$proto" = "PRP" ]; then
153+
setup_prp_topo
154+
else
155+
check_err 1 "Unknown protocol (${proto})"
156+
fi
157+
}
158+
159+
check_ping()
160+
{
161+
local node="$1"
162+
local dst="$2"
163+
local ping_args="-q -i 0.01 -c 400"
164+
165+
log_info "Running ping $node -> $dst"
166+
# shellcheck disable=SC2086
167+
output=$(ip netns exec "$node" ping $ping_args "$dst" | \
168+
grep "packets transmitted")
169+
log_info "$output"
170+
171+
dups=0
172+
loss=0
173+
174+
if [[ "$output" =~ \+([0-9]+)" duplicates" ]]; then
175+
dups="${BASH_REMATCH[1]}"
176+
fi
177+
if [[ "$output" =~ ([0-9\.]+\%)" packet loss" ]]; then
178+
loss="${BASH_REMATCH[1]}"
179+
fi
180+
181+
check_err "$dups" "Unexpected duplicate packets (${dups})"
182+
if [ "$loss" != "0%" ]; then
183+
check_err 1 "Unexpected packet loss (${loss})"
184+
fi
185+
}
186+
187+
test_clean()
188+
{
189+
local proto="$1"
190+
191+
RET=0
192+
tname="${FUNCNAME[0]} - ${proto}"
193+
194+
setup_topo "$proto"
195+
if ((RET != ksft_pass)); then
196+
log_test "${tname} setup"
197+
return
198+
fi
199+
200+
check_ping "$node1" "100.64.0.2"
201+
202+
log_test "${tname}"
203+
}
204+
205+
test_clean_hsrv0()
206+
{
207+
test_clean "HSRv0"
208+
}
209+
210+
test_clean_hsrv1()
211+
{
212+
test_clean "HSRv1"
213+
}
214+
215+
test_clean_prp()
216+
{
217+
test_clean "PRP"
218+
}
219+
220+
test_cut_link()
221+
{
222+
local proto="$1"
223+
224+
RET=0
225+
tname="${FUNCNAME[0]} - ${proto}"
226+
227+
setup_topo "$proto"
228+
if ((RET != ksft_pass)); then
229+
log_test "${tname} setup"
230+
return
231+
fi
232+
233+
# Cutting link from subshell, so check_ping can run in the normal shell
234+
# with access to global variables from the test harness.
235+
(
236+
sleep 2
237+
log_info "Cutting link"
238+
ip -net "$node1" link set vethB down
239+
) &
240+
check_ping "$node1" "100.64.0.2"
241+
242+
wait
243+
log_test "${tname}"
244+
}
245+
246+
247+
test_cut_link_hsrv0()
248+
{
249+
test_cut_link "HSRv0"
250+
}
251+
252+
test_cut_link_hsrv1()
253+
{
254+
test_cut_link "HSRv1"
255+
}
256+
257+
test_cut_link_prp()
258+
{
259+
test_cut_link "PRP"
260+
}
261+
262+
cleanup()
263+
{
264+
cleanup_all_ns
265+
}
266+
267+
trap cleanup EXIT
268+
269+
tests_run
270+
271+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)