Skip to content

Commit 64916b5

Browse files
amitcohen1davem330
authored andcommitted
selftests: forwarding: Add speed and auto-negotiation test
Check configurations and packets transference with different variations of autoneg and speed. Test plan: 1. Test force of same speed with autoneg off 2. Test force of different speeds with autoneg off (should fail) 3. One side is autoneg on and other side sets force of common speeds 4. One side is autoneg on and other side only advertises a subset of the common speeds (one speed of the subset) 5. One side is autoneg on and other side only advertises a subset of the common speeds. Check that highest speed is negotiated 6. Test autoneg on, but each side advertises different speeds (should fail) Signed-off-by: Amit Cohen <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8f72a9c commit 64916b5

File tree

1 file changed

+318
-0
lines changed

1 file changed

+318
-0
lines changed
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
ALL_TESTS="
5+
same_speeds_autoneg_off
6+
different_speeds_autoneg_off
7+
combination_of_neg_on_and_off
8+
advertise_subset_of_speeds
9+
check_highest_speed_is_chosen
10+
different_speeds_autoneg_on
11+
"
12+
NUM_NETIFS=2
13+
source lib.sh
14+
source ethtool_lib.sh
15+
16+
h1_create()
17+
{
18+
simple_if_init $h1 192.0.2.1/24
19+
}
20+
21+
h1_destroy()
22+
{
23+
simple_if_fini $h1 192.0.2.1/24
24+
}
25+
26+
h2_create()
27+
{
28+
simple_if_init $h2 192.0.2.2/24
29+
}
30+
31+
h2_destroy()
32+
{
33+
simple_if_fini $h2 192.0.2.2/24
34+
}
35+
36+
setup_prepare()
37+
{
38+
h1=${NETIFS[p1]}
39+
h2=${NETIFS[p2]}
40+
41+
h1_create
42+
h2_create
43+
}
44+
45+
cleanup()
46+
{
47+
pre_cleanup
48+
49+
h2_destroy
50+
h1_destroy
51+
}
52+
53+
different_speeds_get()
54+
{
55+
local dev1=$1; shift
56+
local dev2=$1; shift
57+
local with_mode=$1; shift
58+
local adver=$1; shift
59+
60+
local -a speeds_arr
61+
62+
speeds_arr=($(common_speeds_get $dev1 $dev2 $with_mode $adver))
63+
if [[ ${#speeds_arr[@]} < 2 ]]; then
64+
check_err 1 "cannot check different speeds. There are not enough speeds"
65+
fi
66+
67+
echo ${speeds_arr[0]} ${speeds_arr[1]}
68+
}
69+
70+
same_speeds_autoneg_off()
71+
{
72+
# Check that when each of the reported speeds is forced, the links come
73+
# up and are operational.
74+
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 0))
75+
76+
for speed in "${speeds_arr[@]}"; do
77+
RET=0
78+
ethtool_set $h1 speed $speed autoneg off
79+
ethtool_set $h2 speed $speed autoneg off
80+
81+
setup_wait_dev_with_timeout $h1
82+
setup_wait_dev_with_timeout $h2
83+
ping_do $h1 192.0.2.2
84+
check_err $? "speed $speed autoneg off"
85+
log_test "force of same speed autoneg off"
86+
log_info "speed = $speed"
87+
done
88+
89+
ethtool -s $h2 autoneg on
90+
ethtool -s $h1 autoneg on
91+
}
92+
93+
different_speeds_autoneg_off()
94+
{
95+
# Test that when we force different speeds, links are not up and ping
96+
# fails.
97+
RET=0
98+
99+
local -a speeds_arr=($(different_speeds_get $h1 $h2 0 0))
100+
local speed1=${speeds_arr[0]}
101+
local speed2=${speeds_arr[1]}
102+
103+
ethtool_set $h1 speed $speed1 autoneg off
104+
ethtool_set $h2 speed $speed2 autoneg off
105+
106+
setup_wait_dev_with_timeout $h1
107+
setup_wait_dev_with_timeout $h2
108+
ping_do $h1 192.0.2.2
109+
check_fail $? "ping with different speeds"
110+
111+
log_test "force of different speeds autoneg off"
112+
113+
ethtool -s $h2 autoneg on
114+
ethtool -s $h1 autoneg on
115+
}
116+
117+
combination_of_neg_on_and_off()
118+
{
119+
# Test that when one device is forced to a speed supported by both
120+
# endpoints and the other device is configured to autoneg on, the links
121+
# are up and ping passes.
122+
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))
123+
124+
for speed in "${speeds_arr[@]}"; do
125+
RET=0
126+
ethtool_set $h1 speed $speed autoneg off
127+
128+
setup_wait_dev_with_timeout $h1
129+
setup_wait_dev_with_timeout $h2
130+
ping_do $h1 192.0.2.2
131+
check_err $? "h1-speed=$speed autoneg off, h2 autoneg on"
132+
log_test "one side with autoneg off and another with autoneg on"
133+
log_info "force speed = $speed"
134+
done
135+
136+
ethtool -s $h1 autoneg on
137+
}
138+
139+
hex_speed_value_get()
140+
{
141+
local speed=$1; shift
142+
143+
local shift_size=${speed_values[$speed]}
144+
speed=$((0x1 << $"shift_size"))
145+
printf "%#x" "$speed"
146+
}
147+
148+
subset_of_common_speeds_get()
149+
{
150+
local dev1=$1; shift
151+
local dev2=$1; shift
152+
local adver=$1; shift
153+
154+
local -a speeds_arr=($(common_speeds_get $dev1 $dev2 0 $adver))
155+
local speed_to_advertise=0
156+
local speed_to_remove=${speeds_arr[0]}
157+
speed_to_remove+='base'
158+
159+
local -a speeds_mode_arr=($(common_speeds_get $dev1 $dev2 1 $adver))
160+
161+
for speed in ${speeds_mode_arr[@]}; do
162+
if [[ $speed != $speed_to_remove* ]]; then
163+
speed=$(hex_speed_value_get $speed)
164+
speed_to_advertise=$(($speed_to_advertise | \
165+
$speed))
166+
fi
167+
168+
done
169+
170+
# Convert to hex.
171+
printf "%#x" "$speed_to_advertise"
172+
}
173+
174+
speed_to_advertise_get()
175+
{
176+
# The function returns the hex number that is composed by OR-ing all
177+
# the modes corresponding to the provided speed.
178+
local speed_without_mode=$1; shift
179+
local supported_speeds=("$@"); shift
180+
local speed_to_advertise=0
181+
182+
speed_without_mode+='base'
183+
184+
for speed in ${supported_speeds[@]}; do
185+
if [[ $speed == $speed_without_mode* ]]; then
186+
speed=$(hex_speed_value_get $speed)
187+
speed_to_advertise=$(($speed_to_advertise | \
188+
$speed))
189+
fi
190+
191+
done
192+
193+
# Convert to hex.
194+
printf "%#x" "$speed_to_advertise"
195+
}
196+
197+
advertise_subset_of_speeds()
198+
{
199+
# Test that when one device advertises a subset of speeds and another
200+
# advertises a specific speed (but all modes of this speed), the links
201+
# are up and ping passes.
202+
RET=0
203+
204+
local speed_1_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)
205+
ethtool_set $h1 advertise $speed_1_to_advertise
206+
207+
if [ $RET != 0 ]; then
208+
log_test "advertise subset of speeds"
209+
return
210+
fi
211+
212+
local -a speeds_arr_without_mode=($(common_speeds_get $h1 $h2 0 1))
213+
# Check only speeds that h1 advertised. Remove the first speed.
214+
unset speeds_arr_without_mode[0]
215+
local -a speeds_arr_with_mode=($(common_speeds_get $h1 $h2 1 1))
216+
217+
for speed_value in ${speeds_arr_without_mode[@]}; do
218+
RET=0
219+
local speed_2_to_advertise=$(speed_to_advertise_get $speed_value \
220+
"${speeds_arr_with_mode[@]}")
221+
ethtool_set $h2 advertise $speed_2_to_advertise
222+
223+
setup_wait_dev_with_timeout $h1
224+
setup_wait_dev_with_timeout $h2
225+
ping_do $h1 192.0.2.2
226+
check_err $? "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise ($speed_value)"
227+
228+
log_test "advertise subset of speeds"
229+
log_info "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise"
230+
done
231+
232+
ethtool -s $h2 autoneg on
233+
ethtool -s $h1 autoneg on
234+
}
235+
236+
check_highest_speed_is_chosen()
237+
{
238+
# Test that when one device advertises a subset of speeds, the other
239+
# chooses the highest speed. This test checks configuration without
240+
# traffic.
241+
RET=0
242+
243+
local max_speed
244+
local chosen_speed
245+
local speed_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)
246+
247+
ethtool_set $h1 advertise $speed_to_advertise
248+
249+
if [ $RET != 0 ]; then
250+
log_test "check highest speed"
251+
return
252+
fi
253+
254+
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))
255+
# Remove the first speed, h1 does not advertise this speed.
256+
unset speeds_arr[0]
257+
258+
max_speed=${speeds_arr[0]}
259+
for current in ${speeds_arr[@]}; do
260+
if [[ $current -gt $max_speed ]]; then
261+
max_speed=$current
262+
fi
263+
done
264+
265+
setup_wait_dev_with_timeout $h1
266+
setup_wait_dev_with_timeout $h2
267+
chosen_speed=$(ethtool $h1 | grep 'Speed:')
268+
chosen_speed=${chosen_speed%"Mb/s"*}
269+
chosen_speed=${chosen_speed#*"Speed: "}
270+
((chosen_speed == max_speed))
271+
check_err $? "h1 advertise $speed_to_advertise, h2 sync to speed $chosen_speed"
272+
273+
log_test "check highest speed"
274+
275+
ethtool -s $h2 autoneg on
276+
ethtool -s $h1 autoneg on
277+
}
278+
279+
different_speeds_autoneg_on()
280+
{
281+
# Test that when we configure links to advertise different speeds,
282+
# links are not up and ping fails.
283+
RET=0
284+
285+
local -a speeds=($(different_speeds_get $h1 $h2 1 1))
286+
local speed1=${speeds[0]}
287+
local speed2=${speeds[1]}
288+
289+
speed1=$(hex_speed_value_get $speed1)
290+
speed2=$(hex_speed_value_get $speed2)
291+
292+
ethtool_set $h1 advertise $speed1
293+
ethtool_set $h2 advertise $speed2
294+
295+
if (($RET)); then
296+
setup_wait_dev_with_timeout $h1
297+
setup_wait_dev_with_timeout $h2
298+
ping_do $h1 192.0.2.2
299+
check_fail $? "ping with different speeds autoneg on"
300+
fi
301+
302+
log_test "advertise different speeds autoneg on"
303+
304+
ethtool -s $h2 autoneg on
305+
ethtool -s $h1 autoneg on
306+
}
307+
308+
trap cleanup EXIT
309+
310+
setup_prepare
311+
setup_wait
312+
313+
declare -gA speed_values
314+
eval "speed_values=($(speeds_arr_get))"
315+
316+
tests_run
317+
318+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)