xref: /linux/tools/testing/selftests/net/vlan_bridge_binding.sh (revision 1260ed77798502de9c98020040d2995008de10cc)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4source lib.sh
5
6ALL_TESTS="
7	test_binding_on
8	test_binding_off
9	test_binding_toggle_on
10	test_binding_toggle_off
11	test_binding_toggle_on_when_upper_down
12	test_binding_toggle_off_when_upper_down
13	test_binding_toggle_on_when_lower_down
14	test_binding_toggle_off_when_lower_down
15"
16
17setup_prepare()
18{
19	local port
20
21	ip_link_add br up type bridge vlan_filtering 1
22
23	for port in d1 d2 d3; do
24		ip_link_add $port type veth peer name r$port
25		ip_link_set_up $port
26		ip_link_set_up r$port
27		ip_link_set_master $port br
28	done
29
30	bridge_vlan_add vid 11 dev br self
31	bridge_vlan_add vid 11 dev d1 master
32
33	bridge_vlan_add vid 12 dev br self
34	bridge_vlan_add vid 12 dev d2 master
35
36	bridge_vlan_add vid 13 dev br self
37	bridge_vlan_add vid 13 dev d1 master
38	bridge_vlan_add vid 13 dev d2 master
39
40	bridge_vlan_add vid 14 dev br self
41	bridge_vlan_add vid 14 dev d1 master
42	bridge_vlan_add vid 14 dev d2 master
43	bridge_vlan_add vid 14 dev d3 master
44}
45
46operstate_is()
47{
48	local dev=$1; shift
49	local expect=$1; shift
50
51	local operstate=$(ip -j link show $dev | jq -r .[].operstate)
52	if [[ $operstate == UP ]]; then
53		operstate=1
54	elif [[ $operstate == DOWN || $operstate == LOWERLAYERDOWN ]]; then
55		operstate=0
56	fi
57	echo -n $operstate
58	[[ $operstate == $expect ]]
59}
60
61check_operstate()
62{
63	local dev=$1; shift
64	local expect=$1; shift
65	local operstate
66
67	operstate=$(busywait 1000 \
68			operstate_is "$dev" "$expect")
69	check_err $? "Got operstate of $operstate, expected $expect"
70}
71
72add_one_vlan()
73{
74	local link=$1; shift
75	local id=$1; shift
76
77	ip_link_add $link.$id link $link type vlan id $id "$@"
78}
79
80add_vlans()
81{
82	add_one_vlan br 11 "$@"
83	add_one_vlan br 12 "$@"
84	add_one_vlan br 13 "$@"
85	add_one_vlan br 14 "$@"
86}
87
88set_vlans()
89{
90	ip link set dev br.11 "$@"
91	ip link set dev br.12 "$@"
92	ip link set dev br.13 "$@"
93	ip link set dev br.14 "$@"
94}
95
96down_netdevs()
97{
98	local dev
99
100	for dev in "$@"; do
101		ip_link_set_down $dev
102	done
103}
104
105check_operstates()
106{
107	local opst_11=$1; shift
108	local opst_12=$1; shift
109	local opst_13=$1; shift
110	local opst_14=$1; shift
111
112	check_operstate br.11 $opst_11
113	check_operstate br.12 $opst_12
114	check_operstate br.13 $opst_13
115	check_operstate br.14 $opst_14
116}
117
118do_test_binding()
119{
120	local inject=$1; shift
121	local what=$1; shift
122	local opsts_d1=$1; shift
123	local opsts_d2=$1; shift
124	local opsts_d12=$1; shift
125	local opsts_d123=$1; shift
126
127	RET=0
128
129	defer_scope_push
130		down_netdevs d1
131		$inject
132		check_operstates $opsts_d1
133	defer_scope_pop
134
135	defer_scope_push
136		down_netdevs d2
137		$inject
138		check_operstates $opsts_d2
139	defer_scope_pop
140
141	defer_scope_push
142		down_netdevs d1 d2
143		$inject
144		check_operstates $opsts_d12
145	defer_scope_pop
146
147	defer_scope_push
148		down_netdevs d1 d2 d3
149		$inject
150		check_operstates $opsts_d123
151	defer_scope_pop
152
153	log_test "Test bridge_binding $what"
154}
155
156do_test_binding_on()
157{
158	local inject=$1; shift
159	local what=$1; shift
160
161	do_test_binding "$inject" "$what"	\
162			"0 1 1 1"		\
163			"1 0 1 1"		\
164			"0 0 0 1"		\
165			"0 0 0 0"
166}
167
168do_test_binding_off()
169{
170	local inject=$1; shift
171	local what=$1; shift
172
173	do_test_binding "$inject" "$what"	\
174			"1 1 1 1"		\
175			"1 1 1 1"		\
176			"1 1 1 1"		\
177			"0 0 0 0"
178}
179
180test_binding_on()
181{
182	add_vlans bridge_binding on
183	set_vlans up
184	do_test_binding_on : "on"
185}
186
187test_binding_off()
188{
189	add_vlans bridge_binding off
190	set_vlans up
191	do_test_binding_off : "off"
192}
193
194test_binding_toggle_on()
195{
196	add_vlans bridge_binding off
197	set_vlans up
198	set_vlans type vlan bridge_binding on
199	do_test_binding_on : "off->on"
200}
201
202test_binding_toggle_off()
203{
204	add_vlans bridge_binding on
205	set_vlans up
206	set_vlans type vlan bridge_binding off
207	do_test_binding_off : "on->off"
208}
209
210dfr_set_binding_on()
211{
212	set_vlans type vlan bridge_binding on
213	defer set_vlans type vlan bridge_binding off
214}
215
216dfr_set_binding_off()
217{
218	set_vlans type vlan bridge_binding off
219	defer set_vlans type vlan bridge_binding on
220}
221
222test_binding_toggle_on_when_lower_down()
223{
224	add_vlans bridge_binding off
225	set_vlans up
226	do_test_binding_on dfr_set_binding_on "off->on when lower down"
227}
228
229test_binding_toggle_off_when_lower_down()
230{
231	add_vlans bridge_binding on
232	set_vlans up
233	do_test_binding_off dfr_set_binding_off "on->off when lower down"
234}
235
236test_binding_toggle_on_when_upper_down()
237{
238	add_vlans bridge_binding off
239	set_vlans type vlan bridge_binding on
240	set_vlans up
241	do_test_binding_on : "off->on when upper down"
242}
243
244test_binding_toggle_off_when_upper_down()
245{
246	add_vlans bridge_binding on
247	set_vlans type vlan bridge_binding off
248	set_vlans up
249	do_test_binding_off : "on->off when upper down"
250}
251
252trap defer_scopes_cleanup EXIT
253setup_prepare
254tests_run
255
256exit $EXIT_STATUS
257