xref: /linux/tools/testing/selftests/net/forwarding/bridge_activity_notify.sh (revision 02aabe00b2e1cc61e7a60616d6044592f12a748c)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +-----------------------+                          +------------------------+
5# | H1 (vrf)              |                          | H2 (vrf)               |
6# | 192.0.2.1/28          |                          | 192.0.2.2/28           |
7# |    + $h1              |                          |    + $h2               |
8# +----|------------------+                          +----|-------------------+
9#      |                                                  |
10# +----|--------------------------------------------------|-------------------+
11# | SW |                                                  |                   |
12# | +--|--------------------------------------------------|-----------------+ |
13# | |  + $swp1                   BR1 (802.1d)             + $swp2           | |
14# | |                                                                       | |
15# | +-----------------------------------------------------------------------+ |
16# +---------------------------------------------------------------------------+
17
18ALL_TESTS="
19	new_inactive_test
20	existing_active_test
21	norefresh_test
22"
23
24NUM_NETIFS=4
25source lib.sh
26
27h1_create()
28{
29	simple_if_init "$h1" 192.0.2.1/28
30	defer simple_if_fini "$h1" 192.0.2.1/28
31}
32
33h2_create()
34{
35	simple_if_init "$h2" 192.0.2.2/28
36	defer simple_if_fini "$h2" 192.0.2.2/28
37}
38
39switch_create()
40{
41	adf_ip_link_add br1 type bridge vlan_filtering 0 mcast_snooping 0 \
42		ageing_time "$LOW_AGEING_TIME"
43	adf_ip_link_set_up br1
44
45	adf_ip_link_set_master "$swp1" br1
46	adf_ip_link_set_up "$swp1"
47
48	adf_ip_link_set_master "$swp2" br1
49	adf_ip_link_set_up "$swp2"
50}
51
52setup_prepare()
53{
54	h1=${NETIFS[p1]}
55	swp1=${NETIFS[p2]}
56
57	swp2=${NETIFS[p3]}
58	h2=${NETIFS[p4]}
59
60	adf_vrf_prepare
61
62	h1_create
63	h2_create
64	switch_create
65}
66
67fdb_active_wait()
68{
69	local mac=$1; shift
70
71	bridge -d fdb get "$mac" br br1 | grep -q -v "inactive"
72}
73
74fdb_inactive_wait()
75{
76	local mac=$1; shift
77
78	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
79}
80
81new_inactive_test()
82{
83	local mac="00:11:22:33:44:55"
84
85	# Add a new FDB entry as static and inactive and check that it
86	# becomes active upon traffic.
87	RET=0
88
89	bridge fdb add "$mac" dev "$swp1" master static activity_notify inactive
90	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
91	check_err $? "FDB entry not present as \"inactive\" when should"
92
93	$MZ "$h1" -c 1 -p 64 -a "$mac" -b bcast -t ip -q
94
95	busywait "$BUSYWAIT_TIMEOUT" fdb_active_wait "$mac"
96	check_err $? "FDB entry present as \"inactive\" when should not"
97
98	log_test "Transition from inactive to active"
99
100	bridge fdb del "$mac" dev "$swp1" master
101}
102
103existing_active_test()
104{
105	local mac="00:11:22:33:44:55"
106	local ageing_time
107
108	# Enable activity notifications on an existing dynamic FDB entry and
109	# check that it becomes inactive after the ageing time passed.
110	RET=0
111
112	bridge fdb add "$mac" dev "$swp1" master dynamic
113	bridge fdb replace "$mac" dev "$swp1" master static activity_notify norefresh
114
115	bridge -d fdb get "$mac" br br1 | grep -q "activity_notify"
116	check_err $? "FDB entry not present as \"activity_notify\" when should"
117
118	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
119	check_fail $? "FDB entry present as \"inactive\" when should not"
120
121	ageing_time=$(bridge_ageing_time_get br1)
122	slowwait $((ageing_time * 2)) fdb_inactive_wait "$mac"
123	check_err $? "FDB entry not present as \"inactive\" when should"
124
125	log_test "Transition from active to inactive"
126
127	bridge fdb del "$mac" dev "$swp1" master
128}
129
130norefresh_test()
131{
132	local mac="00:11:22:33:44:55"
133	local updated_time
134
135	# Check that the "updated" time is reset when replacing an FDB entry
136	# without the "norefresh" keyword and that it is not reset when
137	# replacing with the "norefresh" keyword.
138	RET=0
139
140	bridge fdb add "$mac" dev "$swp1" master static
141	sleep 1
142
143	bridge fdb replace "$mac" dev "$swp1" master static activity_notify
144	updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
145	if [[ $updated_time -ne 0 ]]; then
146		check_err 1 "\"updated\" time was not reset when should"
147	fi
148
149	sleep 1
150	bridge fdb replace "$mac" dev "$swp1" master static norefresh
151	updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
152	if [[ $updated_time -eq 0 ]]; then
153		check_err 1 "\"updated\" time was reset when should not"
154	fi
155
156	log_test "Resetting of \"updated\" time"
157
158	bridge fdb del "$mac" dev "$swp1" master
159}
160
161if ! bridge fdb help 2>&1 | grep -q "activity_notify"; then
162	echo "SKIP: iproute2 too old, missing bridge FDB activity notification control"
163	exit "$ksft_skip"
164fi
165
166trap cleanup EXIT
167
168setup_prepare
169setup_wait
170tests_run
171
172exit "$EXIT_STATUS"
173