xref: /linux/tools/testing/selftests/net/forwarding/bridge_mld.sh (revision f08a1e912d3e60bf3028ea1c5199a609d12cd37c)
1444c8971SNikolay Aleksandrov#!/bin/bash
2444c8971SNikolay Aleksandrov# SPDX-License-Identifier: GPL-2.0
3444c8971SNikolay Aleksandrov
455852f1dSNikolay AleksandrovALL_TESTS="mldv2include_test mldv2inc_allow_test mldv2inc_is_include_test mldv2inc_is_exclude_test \
5d0b19dedSNikolay Aleksandrov	   mldv2inc_to_exclude_test mldv2exc_allow_test mldv2exc_is_include_test \
6a2d667f0SNikolay Aleksandrov	   mldv2exc_is_exclude_test mldv2exc_to_exclude_test mldv2inc_block_test \
7252b353cSNikolay Aleksandrov	   mldv2exc_block_test mldv2exc_timeout_test mldv2star_ex_auto_add_test"
8444c8971SNikolay AleksandrovNUM_NETIFS=4
9444c8971SNikolay AleksandrovCHECK_TC="yes"
10444c8971SNikolay AleksandrovTEST_GROUP="ff02::cc"
11444c8971SNikolay AleksandrovTEST_GROUP_MAC="33:33:00:00:00:cc"
12444c8971SNikolay Aleksandrov
13444c8971SNikolay Aleksandrov# MLDv2 is_in report: grp ff02::cc is_include 2001:db8:1::1,2001:db8:1::2,2001:db8:1::3
14444c8971SNikolay AleksandrovMZPKT_IS_INC="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:54:00:01:fe:80:00:\
15444c8971SNikolay Aleksandrov00:00:00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:\
16444c8971SNikolay Aleksandrov00:05:02:00:00:00:00:8f:00:8e:d9:00:00:00:01:01:00:00:03:ff:02:00:00:00:00:00:00:00:00:00:\
17444c8971SNikolay Aleksandrov00:00:00:00:cc:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01:20:01:0d:b8:00:01:00:00:00:\
18444c8971SNikolay Aleksandrov00:00:00:00:00:00:02:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03"
19f44de2bcSNikolay Aleksandrov# MLDv2 is_in report: grp ff02::cc is_include 2001:db8:1::10,2001:db8:1::11,2001:db8:1::12
20f44de2bcSNikolay AleksandrovMZPKT_IS_INC2="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:54:00:01:fe:80:00:\
21f44de2bcSNikolay Aleksandrov00:00:00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:\
22f44de2bcSNikolay Aleksandrov05:02:00:00:00:00:8f:00:8e:ac:00:00:00:01:01:00:00:03:ff:02:00:00:00:00:00:00:00:00:00:00:00:\
23f44de2bcSNikolay Aleksandrov00:00:cc:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:10:20:01:0d:b8:00:01:00:00:00:00:00:00:\
24f44de2bcSNikolay Aleksandrov00:00:00:11:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:12"
2525ba7c03SNikolay Aleksandrov# MLDv2 is_in report: grp ff02::cc is_include 2001:db8:1::20,2001:db8:1::30
2625ba7c03SNikolay AleksandrovMZPKT_IS_INC3="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:44:00:01:fe:80:00:00:00:\
2725ba7c03SNikolay Aleksandrov00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:\
2825ba7c03SNikolay Aleksandrov00:00:00:8f:00:bc:5a:00:00:00:01:01:00:00:02:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:\
2925ba7c03SNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:30"
300ef10e60SNikolay Aleksandrov# MLDv2 allow report: grp ff02::cc allow 2001:db8:1::10,2001:db8:1::11,2001:db8:1::12
310ef10e60SNikolay AleksandrovMZPKT_ALLOW="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:54:00:01:fe:80:00:00:\
320ef10e60SNikolay Aleksandrov00:00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:\
330ef10e60SNikolay Aleksandrov02:00:00:00:00:8f:00:8a:ac:00:00:00:01:05:00:00:03:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:\
340ef10e60SNikolay Aleksandrov00:cc:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:10:20:01:0d:b8:00:01:00:00:00:00:00:00:00:\
350ef10e60SNikolay Aleksandrov00:00:11:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:12"
360e77581fSNikolay Aleksandrov# MLDv2 allow report: grp ff02::cc allow 2001:db8:1::20,2001:db8:1::30
370e77581fSNikolay AleksandrovMZPKT_ALLOW2="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:44:00:01:fe:80:00:00:00:\
380e77581fSNikolay Aleksandrov00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:\
390e77581fSNikolay Aleksandrov00:00:00:8f:00:b8:5a:00:00:00:01:05:00:00:02:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:\
400e77581fSNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:30"
41f9fcd553SNikolay Aleksandrov# MLDv2 is_ex report: grp ff02::cc is_exclude 2001:db8:1::1,2001:db8:1::2,2001:db8:1::20,2001:db8:1::21
42f9fcd553SNikolay AleksandrovMZPKT_IS_EXC="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:64:00:01:fe:80:00:00:00:\
43f9fcd553SNikolay Aleksandrov00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:\
44f9fcd553SNikolay Aleksandrov00:00:00:8f:00:5f:d0:00:00:00:01:02:00:00:04:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:\
45f9fcd553SNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:02:20:\
46f9fcd553SNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:21"
47d0b19dedSNikolay Aleksandrov# MLDv2 is_ex report: grp ff02::cc is_exclude 2001:db8:1::20,2001:db8:1::30
48d0b19dedSNikolay AleksandrovMZPKT_IS_EXC2="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:44:00:01:fe:80:00:00:00:\
49d0b19dedSNikolay Aleksandrov00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:\
50d0b19dedSNikolay Aleksandrov00:00:00:8f:00:bb:5a:00:00:00:01:02:00:00:02:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:\
51d0b19dedSNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:30"
5255852f1dSNikolay Aleksandrov# MLDv2 to_ex report: grp ff02::cc to_exclude 2001:db8:1::1,2001:db8:1::20,2001:db8:1::30
5355852f1dSNikolay AleksandrovMZPKT_TO_EXC="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:54:00:01:fe:80:00:00:00:\
5455852f1dSNikolay Aleksandrov00:00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:\
5555852f1dSNikolay Aleksandrov00:00:00:8f:00:8b:8e:00:00:00:01:04:00:00:03:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:\
5655852f1dSNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:\
5755852f1dSNikolay Aleksandrov01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:30"
5857386215SNikolay Aleksandrov# MLDv2 block report: grp ff02::cc block 2001:db8:1::1,2001:db8:1::20,2001:db8:1::30
5957386215SNikolay AleksandrovMZPKT_BLOCK="33:33:00:00:00:01:fe:54:00:04:5e:ba:86:dd:60:0a:2d:ae:00:54:00:01:fe:80:00:00:00:00:\
6057386215SNikolay Aleksandrov00:00:fc:54:00:ff:fe:04:5e:ba:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:01:3a:00:05:02:00:00:\
6157386215SNikolay Aleksandrov00:00:8f:00:89:8e:00:00:00:01:06:00:00:03:ff:02:00:00:00:00:00:00:00:00:00:00:00:00:00:cc:20:01:\
6257386215SNikolay Aleksandrov0d:b8:00:01:00:00:00:00:00:00:00:00:00:01:20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:20:20:01:\
6357386215SNikolay Aleksandrov0d:b8:00:01:00:00:00:00:00:00:00:00:00:30"
64444c8971SNikolay Aleksandrov
65444c8971SNikolay Aleksandrovsource lib.sh
66444c8971SNikolay Aleksandrov
67444c8971SNikolay Aleksandrovh1_create()
68444c8971SNikolay Aleksandrov{
69444c8971SNikolay Aleksandrov	simple_if_init $h1 2001:db8:1::1/64
70444c8971SNikolay Aleksandrov}
71444c8971SNikolay Aleksandrov
72444c8971SNikolay Aleksandrovh1_destroy()
73444c8971SNikolay Aleksandrov{
74444c8971SNikolay Aleksandrov	simple_if_fini $h1 2001:db8:1::1/64
75444c8971SNikolay Aleksandrov}
76444c8971SNikolay Aleksandrov
77444c8971SNikolay Aleksandrovh2_create()
78444c8971SNikolay Aleksandrov{
79444c8971SNikolay Aleksandrov	simple_if_init $h2 2001:db8:1::2/64
80444c8971SNikolay Aleksandrov}
81444c8971SNikolay Aleksandrov
82444c8971SNikolay Aleksandrovh2_destroy()
83444c8971SNikolay Aleksandrov{
84444c8971SNikolay Aleksandrov	simple_if_fini $h2 2001:db8:1::2/64
85444c8971SNikolay Aleksandrov}
86444c8971SNikolay Aleksandrov
87444c8971SNikolay Aleksandrovswitch_create()
88444c8971SNikolay Aleksandrov{
89444c8971SNikolay Aleksandrov	ip link add dev br0 type bridge mcast_snooping 1 mcast_query_response_interval 100 \
90444c8971SNikolay Aleksandrov					mcast_mld_version 2 mcast_startup_query_interval 300 \
91444c8971SNikolay Aleksandrov					mcast_querier 1
92444c8971SNikolay Aleksandrov
93444c8971SNikolay Aleksandrov	ip link set dev $swp1 master br0
94444c8971SNikolay Aleksandrov	ip link set dev $swp2 master br0
95444c8971SNikolay Aleksandrov
96444c8971SNikolay Aleksandrov	ip link set dev br0 up
97444c8971SNikolay Aleksandrov	ip link set dev $swp1 up
98444c8971SNikolay Aleksandrov	ip link set dev $swp2 up
99444c8971SNikolay Aleksandrov
100444c8971SNikolay Aleksandrov	# make sure a query has been generated
101444c8971SNikolay Aleksandrov	sleep 5
102444c8971SNikolay Aleksandrov}
103444c8971SNikolay Aleksandrov
104444c8971SNikolay Aleksandrovswitch_destroy()
105444c8971SNikolay Aleksandrov{
106444c8971SNikolay Aleksandrov	ip link set dev $swp2 down
107444c8971SNikolay Aleksandrov	ip link set dev $swp1 down
108444c8971SNikolay Aleksandrov
109444c8971SNikolay Aleksandrov	ip link del dev br0
110444c8971SNikolay Aleksandrov}
111444c8971SNikolay Aleksandrov
112444c8971SNikolay Aleksandrovsetup_prepare()
113444c8971SNikolay Aleksandrov{
114444c8971SNikolay Aleksandrov	h1=${NETIFS[p1]}
115444c8971SNikolay Aleksandrov	swp1=${NETIFS[p2]}
116444c8971SNikolay Aleksandrov
117444c8971SNikolay Aleksandrov	swp2=${NETIFS[p3]}
118444c8971SNikolay Aleksandrov	h2=${NETIFS[p4]}
119444c8971SNikolay Aleksandrov
120444c8971SNikolay Aleksandrov	vrf_prepare
121444c8971SNikolay Aleksandrov
122444c8971SNikolay Aleksandrov	h1_create
123444c8971SNikolay Aleksandrov	h2_create
124444c8971SNikolay Aleksandrov
125444c8971SNikolay Aleksandrov	switch_create
126444c8971SNikolay Aleksandrov}
127444c8971SNikolay Aleksandrov
128444c8971SNikolay Aleksandrovcleanup()
129444c8971SNikolay Aleksandrov{
130444c8971SNikolay Aleksandrov	pre_cleanup
131444c8971SNikolay Aleksandrov
132444c8971SNikolay Aleksandrov	switch_destroy
133444c8971SNikolay Aleksandrov
134444c8971SNikolay Aleksandrov	h2_destroy
135444c8971SNikolay Aleksandrov	h1_destroy
136444c8971SNikolay Aleksandrov
137444c8971SNikolay Aleksandrov	vrf_cleanup
138444c8971SNikolay Aleksandrov}
139444c8971SNikolay Aleksandrov
140444c8971SNikolay Aleksandrovmldv2include_prepare()
141444c8971SNikolay Aleksandrov{
142444c8971SNikolay Aleksandrov	local host1_if=$1
143444c8971SNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2" "2001:db8:1::3")
144444c8971SNikolay Aleksandrov
145444c8971SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_mld_version 2
146444c8971SNikolay Aleksandrov	check_err $? "Could not change bridge MLD version to 2"
147444c8971SNikolay Aleksandrov
148444c8971SNikolay Aleksandrov	$MZ $host1_if $MZPKT_IS_INC -q
149444c8971SNikolay Aleksandrov	sleep 1
150444c8971SNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
151444c8971SNikolay Aleksandrov		| jq -e ".[].mdb[] | \
152444c8971SNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and .source_list != null)" &>/dev/null
153444c8971SNikolay Aleksandrov	check_err $? "Missing *,G entry with source list"
154444c8971SNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
155444c8971SNikolay Aleksandrov		| jq -e ".[].mdb[] | \
156444c8971SNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
157444c8971SNikolay Aleksandrov				.source_list != null and .filter_mode == \"include\")" &>/dev/null
158444c8971SNikolay Aleksandrov	check_err $? "Wrong *,G entry filter mode"
159444c8971SNikolay Aleksandrov	brmcast_check_sg_entries "is_include" "${X[@]}"
160444c8971SNikolay Aleksandrov}
161444c8971SNikolay Aleksandrov
162f9fcd553SNikolay Aleksandrovmldv2exclude_prepare()
163f9fcd553SNikolay Aleksandrov{
164f9fcd553SNikolay Aleksandrov	local host1_if=$1
165f9fcd553SNikolay Aleksandrov	local mac=$2
166f9fcd553SNikolay Aleksandrov	local group=$3
167f9fcd553SNikolay Aleksandrov	local pkt=$4
168f9fcd553SNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2")
169f9fcd553SNikolay Aleksandrov	local Y=("2001:db8:1::20" "2001:db8:1::21")
170f9fcd553SNikolay Aleksandrov
171f9fcd553SNikolay Aleksandrov	mldv2include_prepare $h1
172f9fcd553SNikolay Aleksandrov
173f9fcd553SNikolay Aleksandrov	$MZ $host1_if -c 1 $MZPKT_IS_EXC -q
174f9fcd553SNikolay Aleksandrov	sleep 1
175f9fcd553SNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
176f9fcd553SNikolay Aleksandrov		| jq -e ".[].mdb[] | \
177f9fcd553SNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
178f9fcd553SNikolay Aleksandrov			 .source_list != null and .filter_mode == \"exclude\")" &>/dev/null
179f9fcd553SNikolay Aleksandrov	check_err $? "Wrong *,G entry filter mode"
180f9fcd553SNikolay Aleksandrov
181f9fcd553SNikolay Aleksandrov	brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
182f9fcd553SNikolay Aleksandrov
183f9fcd553SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
184f9fcd553SNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
185f9fcd553SNikolay Aleksandrov
186f9fcd553SNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
187f9fcd553SNikolay Aleksandrov		| jq -e ".[].mdb[] | \
188f9fcd553SNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
189f9fcd553SNikolay Aleksandrov				.source_list != null and
190f9fcd553SNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::3\")" &>/dev/null
191f9fcd553SNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::3 entry still exists"
192f9fcd553SNikolay Aleksandrov}
193f9fcd553SNikolay Aleksandrov
194444c8971SNikolay Aleksandrovmldv2cleanup()
195444c8971SNikolay Aleksandrov{
196444c8971SNikolay Aleksandrov	local port=$1
197444c8971SNikolay Aleksandrov
198444c8971SNikolay Aleksandrov	bridge mdb del dev br0 port $port grp $TEST_GROUP
199444c8971SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_mld_version 1
200444c8971SNikolay Aleksandrov}
201444c8971SNikolay Aleksandrov
202444c8971SNikolay Aleksandrovmldv2include_test()
203444c8971SNikolay Aleksandrov{
204444c8971SNikolay Aleksandrov	RET=0
205444c8971SNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2" "2001:db8:1::3")
206444c8971SNikolay Aleksandrov
207444c8971SNikolay Aleksandrov	mldv2include_prepare $h1
208444c8971SNikolay Aleksandrov
209444c8971SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
210444c8971SNikolay Aleksandrov
211444c8971SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}"
212444c8971SNikolay Aleksandrov	brmcast_check_sg_fwding 0 "2001:db8:1::100"
213444c8971SNikolay Aleksandrov
214444c8971SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP is_include"
215444c8971SNikolay Aleksandrov
216444c8971SNikolay Aleksandrov	mldv2cleanup $swp1
217444c8971SNikolay Aleksandrov}
218444c8971SNikolay Aleksandrov
2190ef10e60SNikolay Aleksandrovmldv2inc_allow_test()
2200ef10e60SNikolay Aleksandrov{
2210ef10e60SNikolay Aleksandrov	RET=0
2220ef10e60SNikolay Aleksandrov	local X=("2001:db8:1::10" "2001:db8:1::11" "2001:db8:1::12")
2230ef10e60SNikolay Aleksandrov
2240ef10e60SNikolay Aleksandrov	mldv2include_prepare $h1
2250ef10e60SNikolay Aleksandrov
2260ef10e60SNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_ALLOW -q
2270ef10e60SNikolay Aleksandrov	sleep 1
2280ef10e60SNikolay Aleksandrov	brmcast_check_sg_entries "allow" "${X[@]}"
2290ef10e60SNikolay Aleksandrov
2300ef10e60SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
2310ef10e60SNikolay Aleksandrov
2320ef10e60SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}"
2330ef10e60SNikolay Aleksandrov	brmcast_check_sg_fwding 0 "2001:db8:1::100"
2340ef10e60SNikolay Aleksandrov
2350ef10e60SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP include -> allow"
2360ef10e60SNikolay Aleksandrov
2370ef10e60SNikolay Aleksandrov	mldv2cleanup $swp1
2380ef10e60SNikolay Aleksandrov}
2390ef10e60SNikolay Aleksandrov
240f44de2bcSNikolay Aleksandrovmldv2inc_is_include_test()
241f44de2bcSNikolay Aleksandrov{
242f44de2bcSNikolay Aleksandrov	RET=0
243f44de2bcSNikolay Aleksandrov	local X=("2001:db8:1::10" "2001:db8:1::11" "2001:db8:1::12")
244f44de2bcSNikolay Aleksandrov
245f44de2bcSNikolay Aleksandrov	mldv2include_prepare $h1
246f44de2bcSNikolay Aleksandrov
247f44de2bcSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_IS_INC2 -q
248f44de2bcSNikolay Aleksandrov	sleep 1
249f44de2bcSNikolay Aleksandrov	brmcast_check_sg_entries "is_include" "${X[@]}"
250f44de2bcSNikolay Aleksandrov
251f44de2bcSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
252f44de2bcSNikolay Aleksandrov
253f44de2bcSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}"
254f44de2bcSNikolay Aleksandrov	brmcast_check_sg_fwding 0 "2001:db8:1::100"
255f44de2bcSNikolay Aleksandrov
256f44de2bcSNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP include -> is_include"
257f44de2bcSNikolay Aleksandrov
258f44de2bcSNikolay Aleksandrov	mldv2cleanup $swp1
259f44de2bcSNikolay Aleksandrov}
260f44de2bcSNikolay Aleksandrov
261f9fcd553SNikolay Aleksandrovmldv2inc_is_exclude_test()
262f9fcd553SNikolay Aleksandrov{
263f9fcd553SNikolay Aleksandrov	RET=0
264f9fcd553SNikolay Aleksandrov
265f9fcd553SNikolay Aleksandrov	mldv2exclude_prepare $h1
266f9fcd553SNikolay Aleksandrov
267f9fcd553SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
268f9fcd553SNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
269f9fcd553SNikolay Aleksandrov
270f9fcd553SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP include -> is_exclude"
271f9fcd553SNikolay Aleksandrov
272f9fcd553SNikolay Aleksandrov	mldv2cleanup $swp1
273f9fcd553SNikolay Aleksandrov}
274f9fcd553SNikolay Aleksandrov
27555852f1dSNikolay Aleksandrovmldv2inc_to_exclude_test()
27655852f1dSNikolay Aleksandrov{
27755852f1dSNikolay Aleksandrov	RET=0
27855852f1dSNikolay Aleksandrov	local X=("2001:db8:1::1")
27955852f1dSNikolay Aleksandrov	local Y=("2001:db8:1::20" "2001:db8:1::30")
28055852f1dSNikolay Aleksandrov
28155852f1dSNikolay Aleksandrov	mldv2include_prepare $h1
28255852f1dSNikolay Aleksandrov
28355852f1dSNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 500
28455852f1dSNikolay Aleksandrov	check_err $? "Could not change mcast_last_member_interval to 5s"
28555852f1dSNikolay Aleksandrov
28655852f1dSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_TO_EXC -q
28755852f1dSNikolay Aleksandrov	sleep 1
28855852f1dSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
28955852f1dSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
29055852f1dSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
29155852f1dSNikolay Aleksandrov				.source_list != null and .filter_mode == \"exclude\")" &>/dev/null
29255852f1dSNikolay Aleksandrov	check_err $? "Wrong *,G entry filter mode"
29355852f1dSNikolay Aleksandrov
29455852f1dSNikolay Aleksandrov	brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
29555852f1dSNikolay Aleksandrov
29655852f1dSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
29755852f1dSNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
29855852f1dSNikolay Aleksandrov
29955852f1dSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
30055852f1dSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
30155852f1dSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
30255852f1dSNikolay Aleksandrov				.source_list != null and
30355852f1dSNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::2\")" &>/dev/null
30455852f1dSNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::2 entry still exists"
30555852f1dSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
30655852f1dSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
30755852f1dSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
30855852f1dSNikolay Aleksandrov				.source_list != null and
30955852f1dSNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::21\")" &>/dev/null
31055852f1dSNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::21 entry still exists"
31155852f1dSNikolay Aleksandrov
31255852f1dSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
31355852f1dSNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
31455852f1dSNikolay Aleksandrov
31555852f1dSNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP include -> to_exclude"
31655852f1dSNikolay Aleksandrov
31755852f1dSNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 100
31855852f1dSNikolay Aleksandrov
31955852f1dSNikolay Aleksandrov	mldv2cleanup $swp1
32055852f1dSNikolay Aleksandrov}
32155852f1dSNikolay Aleksandrov
3220e77581fSNikolay Aleksandrovmldv2exc_allow_test()
3230e77581fSNikolay Aleksandrov{
3240e77581fSNikolay Aleksandrov	RET=0
3250e77581fSNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2" "2001:db8:1::20" "2001:db8:1::30")
3260e77581fSNikolay Aleksandrov	local Y=("2001:db8:1::21")
3270e77581fSNikolay Aleksandrov
3280e77581fSNikolay Aleksandrov	mldv2exclude_prepare $h1
3290e77581fSNikolay Aleksandrov
3300e77581fSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_ALLOW2 -q
3310e77581fSNikolay Aleksandrov	sleep 1
3320e77581fSNikolay Aleksandrov	brmcast_check_sg_entries "allow" "${X[@]}" "${Y[@]}"
3330e77581fSNikolay Aleksandrov
3340e77581fSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
3350e77581fSNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
3360e77581fSNikolay Aleksandrov
3370e77581fSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
3380e77581fSNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
3390e77581fSNikolay Aleksandrov
3400e77581fSNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP exclude -> allow"
3410e77581fSNikolay Aleksandrov
3420e77581fSNikolay Aleksandrov	mldv2cleanup $swp1
3430e77581fSNikolay Aleksandrov}
3440e77581fSNikolay Aleksandrov
34525ba7c03SNikolay Aleksandrovmldv2exc_is_include_test()
34625ba7c03SNikolay Aleksandrov{
34725ba7c03SNikolay Aleksandrov	RET=0
34825ba7c03SNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2" "2001:db8:1::20" "2001:db8:1::30")
34925ba7c03SNikolay Aleksandrov	local Y=("2001:db8:1::21")
35025ba7c03SNikolay Aleksandrov
35125ba7c03SNikolay Aleksandrov	mldv2exclude_prepare $h1
35225ba7c03SNikolay Aleksandrov
35325ba7c03SNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_IS_INC3 -q
35425ba7c03SNikolay Aleksandrov	sleep 1
35525ba7c03SNikolay Aleksandrov	brmcast_check_sg_entries "is_include" "${X[@]}" "${Y[@]}"
35625ba7c03SNikolay Aleksandrov
35725ba7c03SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
35825ba7c03SNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
35925ba7c03SNikolay Aleksandrov
36025ba7c03SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
36125ba7c03SNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
36225ba7c03SNikolay Aleksandrov
36325ba7c03SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP exclude -> is_include"
36425ba7c03SNikolay Aleksandrov
36525ba7c03SNikolay Aleksandrov	mldv2cleanup $swp1
36625ba7c03SNikolay Aleksandrov}
36725ba7c03SNikolay Aleksandrov
368d0b19dedSNikolay Aleksandrovmldv2exc_is_exclude_test()
369d0b19dedSNikolay Aleksandrov{
370d0b19dedSNikolay Aleksandrov	RET=0
371d0b19dedSNikolay Aleksandrov	local X=("2001:db8:1::30")
372d0b19dedSNikolay Aleksandrov	local Y=("2001:db8:1::20")
373d0b19dedSNikolay Aleksandrov
374d0b19dedSNikolay Aleksandrov	mldv2exclude_prepare $h1
375d0b19dedSNikolay Aleksandrov
376d0b19dedSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_IS_EXC2 -q
377d0b19dedSNikolay Aleksandrov	sleep 1
378d0b19dedSNikolay Aleksandrov	brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
379d0b19dedSNikolay Aleksandrov
380d0b19dedSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
381d0b19dedSNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
382d0b19dedSNikolay Aleksandrov
383d0b19dedSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
384d0b19dedSNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
385d0b19dedSNikolay Aleksandrov
386d0b19dedSNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP exclude -> is_exclude"
387d0b19dedSNikolay Aleksandrov
388d0b19dedSNikolay Aleksandrov	mldv2cleanup $swp1
389d0b19dedSNikolay Aleksandrov}
390d0b19dedSNikolay Aleksandrov
3919eb4394dSNikolay Aleksandrovmldv2exc_to_exclude_test()
3929eb4394dSNikolay Aleksandrov{
3939eb4394dSNikolay Aleksandrov	RET=0
3949eb4394dSNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::30")
3959eb4394dSNikolay Aleksandrov	local Y=("2001:db8:1::20")
3969eb4394dSNikolay Aleksandrov
3979eb4394dSNikolay Aleksandrov	mldv2exclude_prepare $h1
3989eb4394dSNikolay Aleksandrov
3999eb4394dSNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 500
4009eb4394dSNikolay Aleksandrov	check_err $? "Could not change mcast_last_member_interval to 5s"
4019eb4394dSNikolay Aleksandrov
4029eb4394dSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_TO_EXC -q
4039eb4394dSNikolay Aleksandrov	sleep 1
4049eb4394dSNikolay Aleksandrov	brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
4059eb4394dSNikolay Aleksandrov
4069eb4394dSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
4079eb4394dSNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
4089eb4394dSNikolay Aleksandrov
4099eb4394dSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
4109eb4394dSNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
4119eb4394dSNikolay Aleksandrov
4129eb4394dSNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP exclude -> to_exclude"
4139eb4394dSNikolay Aleksandrov
4149eb4394dSNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 100
4159eb4394dSNikolay Aleksandrov
4169eb4394dSNikolay Aleksandrov	mldv2cleanup $swp1
4179eb4394dSNikolay Aleksandrov}
4189eb4394dSNikolay Aleksandrov
41957386215SNikolay Aleksandrovmldv2inc_block_test()
42057386215SNikolay Aleksandrov{
42157386215SNikolay Aleksandrov	RET=0
42257386215SNikolay Aleksandrov	local X=("2001:db8:1::2" "2001:db8:1::3")
42357386215SNikolay Aleksandrov
42457386215SNikolay Aleksandrov	mldv2include_prepare $h1
42557386215SNikolay Aleksandrov
42657386215SNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_BLOCK -q
42757386215SNikolay Aleksandrov	# make sure the lowered timers have expired (by default 2 seconds)
42857386215SNikolay Aleksandrov	sleep 3
42957386215SNikolay Aleksandrov	brmcast_check_sg_entries "block" "${X[@]}"
43057386215SNikolay Aleksandrov
43157386215SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
43257386215SNikolay Aleksandrov
43357386215SNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
43457386215SNikolay Aleksandrov		| jq -e ".[].mdb[] | \
43557386215SNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
43657386215SNikolay Aleksandrov				.source_list != null and
43757386215SNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::1\")" &>/dev/null
43857386215SNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::1 entry still exists"
43957386215SNikolay Aleksandrov
44057386215SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}"
44157386215SNikolay Aleksandrov	brmcast_check_sg_fwding 0 2001:db8:1::100
44257386215SNikolay Aleksandrov
44357386215SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP include -> block"
44457386215SNikolay Aleksandrov
44557386215SNikolay Aleksandrov	mldv2cleanup $swp1
44657386215SNikolay Aleksandrov}
44757386215SNikolay Aleksandrov
448a2d667f0SNikolay Aleksandrovmldv2exc_block_test()
449a2d667f0SNikolay Aleksandrov{
450a2d667f0SNikolay Aleksandrov	RET=0
451a2d667f0SNikolay Aleksandrov	local X=("2001:db8:1::1" "2001:db8:1::2" "2001:db8:1::30")
452a2d667f0SNikolay Aleksandrov	local Y=("2001:db8:1::20" "2001:db8:1::21")
453a2d667f0SNikolay Aleksandrov
454a2d667f0SNikolay Aleksandrov	mldv2exclude_prepare $h1
455a2d667f0SNikolay Aleksandrov
456a2d667f0SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 500
457a2d667f0SNikolay Aleksandrov	check_err $? "Could not change mcast_last_member_interval to 5s"
458a2d667f0SNikolay Aleksandrov
459a2d667f0SNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_BLOCK -q
460a2d667f0SNikolay Aleksandrov	sleep 1
461a2d667f0SNikolay Aleksandrov	brmcast_check_sg_entries "block" "${X[@]}" "${Y[@]}"
462a2d667f0SNikolay Aleksandrov
463a2d667f0SNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
464a2d667f0SNikolay Aleksandrov	brmcast_check_sg_state 1 "${Y[@]}"
465a2d667f0SNikolay Aleksandrov
466a2d667f0SNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}" 2001:db8:1::100
467a2d667f0SNikolay Aleksandrov	brmcast_check_sg_fwding 0 "${Y[@]}"
468a2d667f0SNikolay Aleksandrov
469a2d667f0SNikolay Aleksandrov	log_test "MLDv2 report $TEST_GROUP exclude -> block"
470a2d667f0SNikolay Aleksandrov
471a2d667f0SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_last_member_interval 100
472a2d667f0SNikolay Aleksandrov
473a2d667f0SNikolay Aleksandrov	mldv2cleanup $swp1
474a2d667f0SNikolay Aleksandrov}
475a2d667f0SNikolay Aleksandrov
476d598cc6aSNikolay Aleksandrovmldv2exc_timeout_test()
477d598cc6aSNikolay Aleksandrov{
478d598cc6aSNikolay Aleksandrov	RET=0
479d598cc6aSNikolay Aleksandrov	local X=("2001:db8:1::20" "2001:db8:1::30")
480d598cc6aSNikolay Aleksandrov
481*06080ea2SNikolay Aleksandrov	# GMI should be 5 seconds
48234d7ecb3SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_query_interval 100 \
48334d7ecb3SNikolay Aleksandrov					mcast_query_response_interval 100 \
484*06080ea2SNikolay Aleksandrov					mcast_membership_interval 500
485d598cc6aSNikolay Aleksandrov
486d598cc6aSNikolay Aleksandrov	mldv2exclude_prepare $h1
48734d7ecb3SNikolay Aleksandrov	ip link set dev br0 type bridge mcast_query_interval 500 \
48834d7ecb3SNikolay Aleksandrov					mcast_query_response_interval 500 \
48934d7ecb3SNikolay Aleksandrov					mcast_membership_interval 1500
49034d7ecb3SNikolay Aleksandrov
491d598cc6aSNikolay Aleksandrov	$MZ $h1 -c 1 $MZPKT_ALLOW2 -q
492*06080ea2SNikolay Aleksandrov	sleep 5
493d598cc6aSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
494d598cc6aSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
495d598cc6aSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
496d598cc6aSNikolay Aleksandrov				.source_list != null and .filter_mode == \"include\")" &>/dev/null
497d598cc6aSNikolay Aleksandrov	check_err $? "Wrong *,G entry filter mode"
498d598cc6aSNikolay Aleksandrov
499d598cc6aSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
500d598cc6aSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
501d598cc6aSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
502d598cc6aSNikolay Aleksandrov				.source_list != null and
503d598cc6aSNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::1\")" &>/dev/null
504d598cc6aSNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::1 entry still exists"
505d598cc6aSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
506d598cc6aSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
507d598cc6aSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and \
508d598cc6aSNikolay Aleksandrov				.source_list != null and
509d598cc6aSNikolay Aleksandrov				.source_list[].address == \"2001:db8:1::2\")" &>/dev/null
510d598cc6aSNikolay Aleksandrov	check_fail $? "Wrong *,G entry source list, 2001:db8:1::2 entry still exists"
511d598cc6aSNikolay Aleksandrov
512d598cc6aSNikolay Aleksandrov	brmcast_check_sg_entries "allow" "${X[@]}"
513d598cc6aSNikolay Aleksandrov
514d598cc6aSNikolay Aleksandrov	brmcast_check_sg_state 0 "${X[@]}"
515d598cc6aSNikolay Aleksandrov
516d598cc6aSNikolay Aleksandrov	brmcast_check_sg_fwding 1 "${X[@]}"
517d598cc6aSNikolay Aleksandrov	brmcast_check_sg_fwding 0 2001:db8:1::100
518d598cc6aSNikolay Aleksandrov
519d598cc6aSNikolay Aleksandrov	log_test "MLDv2 group $TEST_GROUP exclude timeout"
520d598cc6aSNikolay Aleksandrov
521d598cc6aSNikolay Aleksandrov	ip link set dev br0 type bridge mcast_query_interval 12500 \
52234d7ecb3SNikolay Aleksandrov					mcast_query_response_interval 1000 \
52334d7ecb3SNikolay Aleksandrov					mcast_membership_interval 26000
524d598cc6aSNikolay Aleksandrov
525d598cc6aSNikolay Aleksandrov	mldv2cleanup $swp1
526d598cc6aSNikolay Aleksandrov}
527d598cc6aSNikolay Aleksandrov
528252b353cSNikolay Aleksandrovmldv2star_ex_auto_add_test()
529252b353cSNikolay Aleksandrov{
530252b353cSNikolay Aleksandrov	RET=0
531252b353cSNikolay Aleksandrov
532252b353cSNikolay Aleksandrov	mldv2exclude_prepare $h1
533252b353cSNikolay Aleksandrov
534252b353cSNikolay Aleksandrov	$MZ $h2 -c 1 $MZPKT_IS_INC -q
535252b353cSNikolay Aleksandrov	sleep 1
536252b353cSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
537252b353cSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
538252b353cSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and .src == \"2001:db8:1::3\" and \
539252b353cSNikolay Aleksandrov				.port == \"$swp1\")" &>/dev/null
540252b353cSNikolay Aleksandrov	check_err $? "S,G entry for *,G port doesn't exist"
541252b353cSNikolay Aleksandrov
542252b353cSNikolay Aleksandrov	bridge -j -d -s mdb show dev br0 \
543252b353cSNikolay Aleksandrov		| jq -e ".[].mdb[] | \
544252b353cSNikolay Aleksandrov			 select(.grp == \"$TEST_GROUP\" and .src == \"2001:db8:1::3\" and \
545252b353cSNikolay Aleksandrov				.port == \"$swp1\" and \
546252b353cSNikolay Aleksandrov				.flags[] == \"added_by_star_ex\")" &>/dev/null
547252b353cSNikolay Aleksandrov	check_err $? "Auto-added S,G entry doesn't have added_by_star_ex flag"
548252b353cSNikolay Aleksandrov
549252b353cSNikolay Aleksandrov	brmcast_check_sg_fwding 1 2001:db8:1::3
550252b353cSNikolay Aleksandrov
551252b353cSNikolay Aleksandrov	log_test "MLDv2 S,G port entry automatic add to a *,G port"
552252b353cSNikolay Aleksandrov
553252b353cSNikolay Aleksandrov	mldv2cleanup $swp1
554252b353cSNikolay Aleksandrov	mldv2cleanup $swp2
555252b353cSNikolay Aleksandrov}
556252b353cSNikolay Aleksandrov
557444c8971SNikolay Aleksandrovtrap cleanup EXIT
558444c8971SNikolay Aleksandrov
559444c8971SNikolay Aleksandrovsetup_prepare
560444c8971SNikolay Aleksandrovsetup_wait
561444c8971SNikolay Aleksandrov
562444c8971SNikolay Aleksandrovtests_run
563444c8971SNikolay Aleksandrov
564444c8971SNikolay Aleksandrovexit $EXIT_STATUS
565