xref: /linux/tools/testing/selftests/net/forwarding/bridge_activity_notify.sh (revision 0d2ab5f922e75d10162e7199826e14df9cfae5cc)
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	ip_link_add br1 type bridge vlan_filtering 0 mcast_snooping 0 \
42		ageing_time "$LOW_AGEING_TIME"
43	ip_link_set_up br1
44
45	ip_link_set_master "$swp1" br1
46	ip_link_set_up "$swp1"
47
48	ip_link_set_master "$swp2" br1
49	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	vrf_prepare
61	defer vrf_cleanup
62
63	h1_create
64	h2_create
65	switch_create
66}
67
68fdb_active_wait()
69{
70	local mac=$1; shift
71
72	bridge -d fdb get "$mac" br br1 | grep -q -v "inactive"
73}
74
75fdb_inactive_wait()
76{
77	local mac=$1; shift
78
79	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
80}
81
82new_inactive_test()
83{
84	local mac="00:11:22:33:44:55"
85
86	# Add a new FDB entry as static and inactive and check that it
87	# becomes active upon traffic.
88	RET=0
89
90	bridge fdb add "$mac" dev "$swp1" master static activity_notify inactive
91	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
92	check_err $? "FDB entry not present as \"inactive\" when should"
93
94	$MZ "$h1" -c 1 -p 64 -a "$mac" -b bcast -t ip -q
95
96	busywait "$BUSYWAIT_TIMEOUT" fdb_active_wait "$mac"
97	check_err $? "FDB entry present as \"inactive\" when should not"
98
99	log_test "Transition from inactive to active"
100
101	bridge fdb del "$mac" dev "$swp1" master
102}
103
104existing_active_test()
105{
106	local mac="00:11:22:33:44:55"
107	local ageing_time
108
109	# Enable activity notifications on an existing dynamic FDB entry and
110	# check that it becomes inactive after the ageing time passed.
111	RET=0
112
113	bridge fdb add "$mac" dev "$swp1" master dynamic
114	bridge fdb replace "$mac" dev "$swp1" master static activity_notify norefresh
115
116	bridge -d fdb get "$mac" br br1 | grep -q "activity_notify"
117	check_err $? "FDB entry not present as \"activity_notify\" when should"
118
119	bridge -d fdb get "$mac" br br1 | grep -q "inactive"
120	check_fail $? "FDB entry present as \"inactive\" when should not"
121
122	ageing_time=$(bridge_ageing_time_get br1)
123	slowwait $((ageing_time * 2)) fdb_inactive_wait "$mac"
124	check_err $? "FDB entry not present as \"inactive\" when should"
125
126	log_test "Transition from active to inactive"
127
128	bridge fdb del "$mac" dev "$swp1" master
129}
130
131norefresh_test()
132{
133	local mac="00:11:22:33:44:55"
134	local updated_time
135
136	# Check that the "updated" time is reset when replacing an FDB entry
137	# without the "norefresh" keyword and that it is not reset when
138	# replacing with the "norefresh" keyword.
139	RET=0
140
141	bridge fdb add "$mac" dev "$swp1" master static
142	sleep 1
143
144	bridge fdb replace "$mac" dev "$swp1" master static activity_notify
145	updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
146	if [[ $updated_time -ne 0 ]]; then
147		check_err 1 "\"updated\" time was not reset when should"
148	fi
149
150	sleep 1
151	bridge fdb replace "$mac" dev "$swp1" master static norefresh
152	updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
153	if [[ $updated_time -eq 0 ]]; then
154		check_err 1 "\"updated\" time was reset when should not"
155	fi
156
157	log_test "Resetting of \"updated\" time"
158
159	bridge fdb del "$mac" dev "$swp1" master
160}
161
162if ! bridge fdb help 2>&1 | grep -q "activity_notify"; then
163	echo "SKIP: iproute2 too old, missing bridge FDB activity notification control"
164	exit "$ksft_skip"
165fi
166
167trap cleanup EXIT
168
169setup_prepare
170setup_wait
171tests_run
172
173exit "$EXIT_STATUS"
174