xref: /linux/tools/testing/selftests/drivers/net/bonding/bond_lacp_strict.sh (revision 637315cb400eed1dbe721954fea437a61a2d65b2)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Testing if bond lacp_strict works
5#
6#          Partner (p_ns)
7#  +--------------------------+
8#  |          bond0           |
9#  |            +             |
10#  |      eth0  |  eth1       |
11#  |        +---+---+         |
12#  |        |       |         |
13#  +--------------------------+
14#  |        | eth0  | eth1    |
15#  |        |       |         |
16#  |(br_ns) | br0   | br1     |
17#  |        |       |         |
18#  |        | eth2  | eth3    |
19#  +--------------------------+
20#  |        |       |         |
21#  |        +---+---+         |
22#  |      eth0  |  eth1       |
23#  |            +             |
24#  |          bond0           |
25#  +--------------------------+
26#         Dut (d_ns)
27
28lib_dir=$(dirname "$0")
29# shellcheck disable=SC1090
30source "$lib_dir"/../../../net/lib.sh
31
32COLLECTING_DISTRIBUTING_MASK=48
33COLLECTING_DISTRIBUTING=48
34FAILED=0
35
36setup_links()
37{
38	# shellcheck disable=SC2154
39	ip -n "${p_ns}" link add eth0 type veth peer name eth0 netns "${br_ns}"
40	ip -n "${p_ns}" link add eth1 type veth peer name eth1 netns "${br_ns}"
41	ip -n "${d_ns}" link add eth0 type veth peer name eth2 netns "${br_ns}"
42	ip -n "${d_ns}" link add eth1 type veth peer name eth3 netns "${br_ns}"
43
44	ip -n "${br_ns}" link add br0 type bridge
45	ip -n "${br_ns}" link add br1 type bridge
46
47	ip -n "${br_ns}" link set dev br0 type bridge stp_state 0
48	ip -n "${br_ns}" link set dev br1 type bridge stp_state 0
49
50	ip -n "${br_ns}" link set eth0 master br0
51	ip -n "${br_ns}" link set eth2 master br0
52	ip -n "${br_ns}" link set eth1 master br1
53	ip -n "${br_ns}" link set eth3 master br1
54
55	# Allow LACP trames forwarding on bridge ports
56	ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask"
57	ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask"
58	ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask"
59	ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask"
60
61	ip -n "${br_ns}" link set eth0 up
62	ip -n "${br_ns}" link set eth2 up
63	ip -n "${br_ns}" link set eth1 up
64	ip -n "${br_ns}" link set eth3 up
65
66	ip -n "${br_ns}" link set br0 up
67	ip -n "${br_ns}" link set br1 up
68
69	ip -n "${d_ns}" link add bond0 type bond mode 802.3ad miimon 100 \
70		lacp_rate fast min_links 1
71	ip -n "${p_ns}" link add bond0 type bond mode 802.3ad miimon 100 \
72		lacp_rate fast min_links 1
73
74	ip -n "${d_ns}" link set eth0 master bond0
75	ip -n "${d_ns}" link set eth1 master bond0
76	ip -n "${p_ns}" link set eth0 master bond0
77	ip -n "${p_ns}" link set eth1 master bond0
78
79	ip -n "${d_ns}" link set bond0 up
80	ip -n "${p_ns}" link set bond0 up
81}
82
83test_master_carrier() {
84	local expected=$1
85	local mode_name=$2
86	local carrier
87
88	carrier=$(ip netns exec "${d_ns}" cat /sys/class/net/bond0/carrier)
89	[ "$carrier" == "1" ] && carrier="up" || carrier="down"
90
91	[ "$carrier" == "$expected" ] && return
92
93	echo "FAIL: Expected carrier $expected in lacp_strict $mode_name mode, got $carrier"
94
95	RET=1
96
97}
98
99compare_state() {
100	local actual_state=$1
101	local expected_state=$2
102	local iface=$3
103	local last_attempt=$4
104
105    [ $((actual_state & COLLECTING_DISTRIBUTING_MASK)) -eq "$expected_state" ] \
106		&& return 0
107
108	[ "$last_attempt" -ne 1 ] && return 1
109
110	printf "FAIL: Expected LACP %s actor state to " "$iface"
111	if [ "$expected_state" -eq $COLLECTING_DISTRIBUTING ]; then
112		echo "be in Collecting/Distributing state"
113	else
114		echo "have neither Collecting nor Distributing set."
115	fi
116
117	return 1
118}
119
120_test_lacp_port_state() {
121	local interface=$1
122	local expected=$2
123	local last_attempt=$3
124	local eth0_actor_state eth1_actor_state
125	local ret=0
126
127	# shellcheck disable=SC2016
128	while IFS='=' read -r k v; do
129		printf -v "$k" '%s' "$v"
130	done < <(
131		ip netns exec "${d_ns}" awk '
132		/^Slave Interface: / { iface=$3 }
133		/details actor lacp pdu:/ { ctx="actor" }
134		/details partner lacp pdu:/ { ctx="partner" }
135		/^[[:space:]]+port state: / {
136			if (ctx == "actor") {
137				gsub(":", "", iface)
138				printf "%s_%s_state=%s\n", iface, ctx, $3
139			}
140		}
141		' /proc/net/bonding/bond0
142	)
143
144	if [ "$interface" == "eth0" ] || [ "$interface" == "both" ]; then
145		compare_state "$eth0_actor_state" "$expected" eth0 "$last_attempt" || ret=1
146	fi
147
148	if [ "$interface" == "eth1" ] || [ "$interface" == "both" ]; then
149		compare_state "$eth1_actor_state" "$expected" eth1 "$last_attempt" || ret=1
150	fi
151
152	return $ret
153}
154
155test_lacp_port_state() {
156	local interface=$1
157	local expected=$2
158	local retry=$3
159	local last_attempt=0
160	local attempt=1
161	local ret=1
162
163	while [ $attempt -le $((retry + 1)) ]; do
164		[ $attempt -eq $((retry + 1)) ] && last_attempt=1
165		_test_lacp_port_state "$interface" "$expected" "$last_attempt" && return
166		((attempt++))
167		sleep 1
168	done
169
170	RET=1
171}
172
173
174trap cleanup_all_ns EXIT
175setup_ns d_ns p_ns br_ns
176setup_links
177
178# Initial state
179RET=0
180mode=off
181test_lacp_port_state both $COLLECTING_DISTRIBUTING 3
182test_master_carrier up $mode
183log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up"
184
185# partner eth0 down, eth1 up
186# (replicate eth0 state to dut eth0 by shutting a bridge port)
187RET=0
188ip -n "${p_ns}" link set eth0 down
189ip -n "${br_ns}" link set eth2 down
190test_lacp_port_state eth0 $FAILED 5
191test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1
192test_master_carrier up $mode
193log_test "bond LACP" "lacp_strict $mode - eth0 down"
194
195# partner eth0 and eth1 down
196RET=0
197ip -n "${p_ns}" link set eth1 down
198ip -n "${br_ns}" link set eth3 down
199test_lacp_port_state both $FAILED 5
200test_master_carrier down $mode # down because of min_links
201log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 down"
202
203# partner eth0 up, eth1 down
204RET=0
205ip -n "${p_ns}" link set eth0 up
206ip -n "${br_ns}" link set eth2 up
207test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60
208test_lacp_port_state eth1 $FAILED 1
209test_master_carrier up $mode
210log_test "bond LACP" "lacp_strict $mode - eth0 up, eth1 down"
211
212# partner eth0 and eth1 up
213RET=0
214ip -n "${p_ns}" link set eth1 up
215ip -n "${br_ns}" link set eth3 up
216test_lacp_port_state both $COLLECTING_DISTRIBUTING 60
217test_master_carrier up $mode
218log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up"
219
220# partner eth0 stops LACP and eth1 up
221RET=0
222ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth0/group_fwd_mask"
223ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth2/group_fwd_mask"
224test_lacp_port_state eth0 $FAILED 5
225test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1
226test_master_carrier up $mode
227log_test "bond LACP" "lacp_strict $mode - eth0 stopped sending LACP"
228
229# partner eth0 and eth1 stop LACP
230RET=0
231ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth1/group_fwd_mask"
232ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth3/group_fwd_mask"
233test_lacp_port_state both $FAILED 5
234test_master_carrier up $mode
235log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP"
236
237# switch to lacp_strict on
238RET=0
239mode=on
240ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode
241test_lacp_port_state both $FAILED 1
242test_master_carrier down $mode
243log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP"
244
245# switch back to lacp_strict off mode
246RET=0
247mode=off
248ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode
249test_lacp_port_state both $FAILED 1
250test_master_carrier up $mode
251log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP"
252
253# eth0 recovers LACP
254RET=0
255ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask"
256ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask"
257test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60
258test_lacp_port_state eth1 $FAILED 1
259test_master_carrier up $mode
260log_test "bond LACP" "lacp_strict $mode - eth0 recovered and eth1 stopped sending LACP"
261
262# eth1 recovers LACP
263RET=0
264ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask"
265ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask"
266test_lacp_port_state both $COLLECTING_DISTRIBUTING 60
267test_master_carrier up $mode
268log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 recovered LACP"
269
270# switch to lacp_strict on
271RET=0
272mode=on
273ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode
274test_lacp_port_state both $COLLECTING_DISTRIBUTING 1
275test_master_carrier up $mode
276log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up"
277
278# partner eth0 down, eth1 up
279RET=0
280ip -n "${p_ns}" link set eth0 down
281ip -n "${br_ns}" link set eth2 down
282test_lacp_port_state eth0 $FAILED 5
283test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1
284test_master_carrier up $mode
285log_test "bond LACP" "lacp_strict $mode - eth0 down"
286
287# partner eth0 and eth1 down
288RET=0
289ip -n "${p_ns}" link set eth1 down
290ip -n "${br_ns}" link set eth3 down
291test_lacp_port_state both $FAILED 5
292test_master_carrier down $mode # down because of min_links
293log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 down"
294
295# partner eth0 up, eth1 down
296RET=0
297ip -n "${p_ns}" link set eth0 up
298ip -n "${br_ns}" link set eth2 up
299test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60
300test_lacp_port_state eth1 $FAILED 1
301test_master_carrier up $mode
302log_test "bond LACP" "lacp_strict $mode - eth0 up, eth1 down"
303
304# partner eth0 and eth1 up
305RET=0
306ip -n "${p_ns}" link set eth1 up
307ip -n "${br_ns}" link set eth3 up
308test_lacp_port_state both $COLLECTING_DISTRIBUTING 60
309test_master_carrier up $mode
310log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up"
311
312# partner eth0 stops LACP and eth1 up
313RET=0
314ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth0/group_fwd_mask"
315ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth2/group_fwd_mask"
316test_lacp_port_state eth0 $FAILED 5
317test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1
318test_master_carrier up $mode
319log_test "bond LACP" "lacp_strict $mode - eth0 stopped sending LACP"
320
321# partner eth0 and eth1 stop LACP
322RET=0
323ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth1/group_fwd_mask"
324ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth3/group_fwd_mask"
325test_lacp_port_state both $FAILED 5
326test_master_carrier down $mode
327log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP"
328
329# eth0 recovers LACP
330RET=0
331ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask"
332ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask"
333test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60
334test_lacp_port_state eth1 $FAILED 1
335test_master_carrier up $mode
336log_test "bond LACP" "lacp_strict $mode - eth0 recovered and eth1 stopped sending LACP"
337
338# eth1 recovers LACP
339# shellcheck disable=SC2034
340RET=0
341ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask"
342ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask"
343test_lacp_port_state both $COLLECTING_DISTRIBUTING 60
344test_master_carrier up $mode
345log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 recovered LACP"
346
347exit "${EXIT_STATUS}"
348