1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4lib_dir=$(dirname $0)/../../../net/forwarding
5
6ALL_TESTS="fw_flash_test params_test regions_test reload_test \
7	   netns_reload_test resource_test"
8NUM_NETIFS=0
9source $lib_dir/lib.sh
10
11BUS_ADDR=10
12PORT_COUNT=4
13DEV_NAME=netdevsim$BUS_ADDR
14SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/
15DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/
16DL_HANDLE=netdevsim/$DEV_NAME
17
18fw_flash_test()
19{
20	RET=0
21
22	devlink dev flash $DL_HANDLE file dummy
23	check_err $? "Failed to flash with status updates on"
24
25	echo "n"> $DEBUGFS_DIR/fw_update_status
26	check_err $? "Failed to disable status updates"
27
28	devlink dev flash $DL_HANDLE file dummy
29	check_err $? "Failed to flash with status updates off"
30
31	log_test "fw flash test"
32}
33
34param_get()
35{
36	local name=$1
37
38	cmd_jq "devlink dev param show $DL_HANDLE name $name -j" \
39	       '.[][][].values[] | select(.cmode == "driverinit").value'
40}
41
42param_set()
43{
44	local name=$1
45	local value=$2
46
47	devlink dev param set $DL_HANDLE name $name cmode driverinit value $value
48}
49
50check_value()
51{
52	local name=$1
53	local phase_name=$2
54	local expected_param_value=$3
55	local expected_debugfs_value=$4
56	local value
57
58	value=$(param_get $name)
59	check_err $? "Failed to get $name param value"
60	[ "$value" == "$expected_param_value" ]
61	check_err $? "Unexpected $phase_name $name param value"
62	value=$(<$DEBUGFS_DIR/$name)
63	check_err $? "Failed to get $name debugfs value"
64	[ "$value" == "$expected_debugfs_value" ]
65	check_err $? "Unexpected $phase_name $name debugfs value"
66}
67
68params_test()
69{
70	RET=0
71
72	local max_macs
73	local test1
74
75	check_value max_macs initial 32 32
76	check_value test1 initial true Y
77
78	param_set max_macs 16
79	check_err $? "Failed to set max_macs param value"
80	param_set test1 false
81	check_err $? "Failed to set test1 param value"
82
83	check_value max_macs post-set 16 32
84	check_value test1 post-set false Y
85
86	devlink dev reload $DL_HANDLE
87
88	check_value max_macs post-reload 16 16
89	check_value test1 post-reload false N
90
91	log_test "params test"
92}
93
94check_region_size()
95{
96	local name=$1
97	local size
98
99	size=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].size')
100	check_err $? "Failed to get $name region size"
101	[ $size -eq 32768 ]
102	check_err $? "Invalid $name region size"
103}
104
105check_region_snapshot_count()
106{
107	local name=$1
108	local phase_name=$2
109	local expected_count=$3
110	local count
111
112	count=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].snapshot | length')
113	[ $count -eq $expected_count ]
114	check_err $? "Unexpected $phase_name snapshot count"
115}
116
117regions_test()
118{
119	RET=0
120
121	local count
122
123	check_region_size dummy
124	check_region_snapshot_count dummy initial 0
125
126	echo ""> $DEBUGFS_DIR/take_snapshot
127	check_err $? "Failed to take first dummy region snapshot"
128	check_region_snapshot_count dummy post-first-snapshot 1
129
130	echo ""> $DEBUGFS_DIR/take_snapshot
131	check_err $? "Failed to take second dummy region snapshot"
132	check_region_snapshot_count dummy post-second-snapshot 2
133
134	echo ""> $DEBUGFS_DIR/take_snapshot
135	check_err $? "Failed to take third dummy region snapshot"
136	check_region_snapshot_count dummy post-third-snapshot 3
137
138	devlink region del $DL_HANDLE/dummy snapshot 1
139	check_err $? "Failed to delete first dummy region snapshot"
140
141	check_region_snapshot_count dummy post-first-delete 2
142
143	log_test "regions test"
144}
145
146reload_test()
147{
148	RET=0
149
150	devlink dev reload $DL_HANDLE
151	check_err $? "Failed to reload"
152
153	log_test "reload test"
154}
155
156netns_reload_test()
157{
158	RET=0
159
160	ip netns add testns1
161	check_err $? "Failed add netns \"testns1\""
162	ip netns add testns2
163	check_err $? "Failed add netns \"testns2\""
164
165	devlink dev reload $DL_HANDLE netns testns1
166	check_err $? "Failed to reload into netns \"testns1\""
167
168	devlink -N testns1 dev reload $DL_HANDLE netns testns2
169	check_err $? "Failed to reload from netns \"testns1\" into netns \"testns2\""
170
171	ip netns del testns2
172	ip netns del testns1
173
174	log_test "netns reload test"
175}
176
177DUMMYDEV="dummytest"
178
179res_val_get()
180{
181	local netns=$1
182	local parentname=$2
183	local name=$3
184	local type=$4
185
186	cmd_jq "devlink -N $netns resource show $DL_HANDLE -j" \
187	       ".[][][] | select(.name == \"$parentname\").resources[] \
188	        | select(.name == \"$name\").$type"
189}
190
191resource_test()
192{
193	RET=0
194
195	ip netns add testns1
196	check_err $? "Failed add netns \"testns1\""
197	ip netns add testns2
198	check_err $? "Failed add netns \"testns2\""
199
200	devlink dev reload $DL_HANDLE netns testns1
201	check_err $? "Failed to reload into netns \"testns1\""
202
203	# Create dummy dev to add the address and routes on.
204
205	ip -n testns1 link add name $DUMMYDEV type dummy
206	check_err $? "Failed create dummy device"
207	ip -n testns1 link set $DUMMYDEV up
208	check_err $? "Failed bring up dummy device"
209	ip -n testns1 a a 192.0.1.1/24 dev $DUMMYDEV
210	check_err $? "Failed add an IP address to dummy device"
211
212	local occ=$(res_val_get testns1 IPv4 fib occ)
213	local limit=$((occ+1))
214
215	# Set fib size limit to handle one another route only.
216
217	devlink -N testns1 resource set $DL_HANDLE path IPv4/fib size $limit
218	check_err $? "Failed to set IPv4/fib resource size"
219	local size_new=$(res_val_get testns1 IPv4 fib size_new)
220	[ "$size_new" -eq "$limit" ]
221	check_err $? "Unexpected \"size_new\" value (got $size_new, expected $limit)"
222
223	devlink -N testns1 dev reload $DL_HANDLE
224	check_err $? "Failed to reload"
225	local size=$(res_val_get testns1 IPv4 fib size)
226	[ "$size" -eq "$limit" ]
227	check_err $? "Unexpected \"size\" value (got $size, expected $limit)"
228
229	# Insert 2 routes, the first is going to be inserted,
230	# the second is expected to fail to be inserted.
231
232	ip -n testns1 r a 192.0.2.0/24 via 192.0.1.2
233	check_err $? "Failed to add route"
234
235	ip -n testns1 r a 192.0.3.0/24 via 192.0.1.2
236	check_fail $? "Unexpected successful route add over limit"
237
238	# Now create another dummy in second network namespace and
239	# insert two routes. That is over the limit of the netdevsim
240	# instance in the first namespace. Move the netdevsim instance
241	# into the second namespace and expect it to fail.
242
243	ip -n testns2 link add name $DUMMYDEV type dummy
244	check_err $? "Failed create dummy device"
245	ip -n testns2 link set $DUMMYDEV up
246	check_err $? "Failed bring up dummy device"
247	ip -n testns2 a a 192.0.1.1/24 dev $DUMMYDEV
248	check_err $? "Failed add an IP address to dummy device"
249	ip -n testns2 r a 192.0.2.0/24 via 192.0.1.2
250	check_err $? "Failed to add route"
251	ip -n testns2 r a 192.0.3.0/24 via 192.0.1.2
252	check_err $? "Failed to add route"
253
254	devlink -N testns1 dev reload $DL_HANDLE netns testns2
255	check_fail $? "Unexpected successful reload from netns \"testns1\" into netns \"testns2\""
256
257	ip netns del testns2
258	ip netns del testns1
259
260	log_test "resource test"
261}
262
263setup_prepare()
264{
265	modprobe netdevsim
266	echo "$BUS_ADDR $PORT_COUNT" > /sys/bus/netdevsim/new_device
267	while [ ! -d $SYSFS_NET_DIR ] ; do :; done
268}
269
270cleanup()
271{
272	pre_cleanup
273	echo "$BUS_ADDR" > /sys/bus/netdevsim/del_device
274	modprobe -r netdevsim
275}
276
277trap cleanup EXIT
278
279setup_prepare
280
281tests_run
282
283exit $EXIT_STATUS
284