xref: /linux/tools/testing/selftests/bpf/test_bpftool_map.sh (revision d9104cec3e8fe4b458b74709853231385779001f)
1*f8b19aecSSlava Imameev#!/bin/sh
2*f8b19aecSSlava Imameev# SPDX-License-Identifier: GPL-2.0
3*f8b19aecSSlava Imameev
4*f8b19aecSSlava Imameev# Kselftest framework requirement - SKIP code is 4.
5*f8b19aecSSlava Imameevksft_skip=4
6*f8b19aecSSlava Imameev
7*f8b19aecSSlava ImameevTESTNAME="bpftool_map"
8*f8b19aecSSlava ImameevBPF_FILE="security_bpf_map.bpf.o"
9*f8b19aecSSlava ImameevBPF_ITER_FILE="bpf_iter_map_elem.bpf.o"
10*f8b19aecSSlava ImameevPROTECTED_MAP_NAME="prot_map"
11*f8b19aecSSlava ImameevNOT_PROTECTED_MAP_NAME="not_prot_map"
12*f8b19aecSSlava ImameevBPF_FS_TMP_PARENT="/tmp"
13*f8b19aecSSlava ImameevBPF_FS_PARENT=$(awk '$3 == "bpf" {print $2; exit}' /proc/mounts)
14*f8b19aecSSlava ImameevBPF_FS_PARENT=${BPF_FS_PARENT:-$BPF_FS_TMP_PARENT}
15*f8b19aecSSlava Imameev# bpftool will mount bpf file system under BPF_DIR if it is not mounted
16*f8b19aecSSlava Imameev# under BPF_FS_PARENT.
17*f8b19aecSSlava ImameevBPF_DIR="$BPF_FS_PARENT/test_$TESTNAME"
18*f8b19aecSSlava ImameevSCRIPT_DIR=$(dirname $(realpath "$0"))
19*f8b19aecSSlava ImameevBPF_FILE_PATH="$SCRIPT_DIR/$BPF_FILE"
20*f8b19aecSSlava ImameevBPF_ITER_FILE_PATH="$SCRIPT_DIR/$BPF_ITER_FILE"
21*f8b19aecSSlava ImameevBPFTOOL_PATH="bpftool"
22*f8b19aecSSlava Imameev# Assume the script is located under tools/testing/selftests/bpf/
23*f8b19aecSSlava ImameevKDIR_ROOT_DIR=$(realpath "$SCRIPT_DIR"/../../../../)
24*f8b19aecSSlava Imameev
25*f8b19aecSSlava Imameev_cleanup()
26*f8b19aecSSlava Imameev{
27*f8b19aecSSlava Imameev	set +eu
28*f8b19aecSSlava Imameev
29*f8b19aecSSlava Imameev	# If BPF_DIR is a mount point this will not remove the mount point itself.
30*f8b19aecSSlava Imameev	[ -d "$BPF_DIR" ] && rm -rf "$BPF_DIR" 2> /dev/null
31*f8b19aecSSlava Imameev
32*f8b19aecSSlava Imameev	# Unmount if BPF filesystem was temporarily created.
33*f8b19aecSSlava Imameev	if [ "$BPF_FS_PARENT" = "$BPF_FS_TMP_PARENT" ]; then
34*f8b19aecSSlava Imameev		# A loop and recursive unmount are required as bpftool might
35*f8b19aecSSlava Imameev		# create multiple mounts. For example, a bind mount of the directory
36*f8b19aecSSlava Imameev		# to itself. The bind mount is created to change mount propagation
37*f8b19aecSSlava Imameev		# flags on an actual mount point.
38*f8b19aecSSlava Imameev		max_attempts=3
39*f8b19aecSSlava Imameev		attempt=0
40*f8b19aecSSlava Imameev		while mountpoint -q "$BPF_DIR" && [ $attempt -lt $max_attempts ]; do
41*f8b19aecSSlava Imameev			umount -R "$BPF_DIR" 2>/dev/null
42*f8b19aecSSlava Imameev			attempt=$((attempt+1))
43*f8b19aecSSlava Imameev		done
44*f8b19aecSSlava Imameev
45*f8b19aecSSlava Imameev		# The directory still exists. Remove it now.
46*f8b19aecSSlava Imameev		[ -d "$BPF_DIR" ] && rm -rf "$BPF_DIR" 2>/dev/null
47*f8b19aecSSlava Imameev	fi
48*f8b19aecSSlava Imameev}
49*f8b19aecSSlava Imameev
50*f8b19aecSSlava Imameevcleanup_skip()
51*f8b19aecSSlava Imameev{
52*f8b19aecSSlava Imameev	echo "selftests: $TESTNAME [SKIP]"
53*f8b19aecSSlava Imameev	_cleanup
54*f8b19aecSSlava Imameev
55*f8b19aecSSlava Imameev	exit $ksft_skip
56*f8b19aecSSlava Imameev}
57*f8b19aecSSlava Imameev
58*f8b19aecSSlava Imameevcleanup()
59*f8b19aecSSlava Imameev{
60*f8b19aecSSlava Imameev	if [ "$?" = 0 ]; then
61*f8b19aecSSlava Imameev		echo "selftests: $TESTNAME [PASS]"
62*f8b19aecSSlava Imameev	else
63*f8b19aecSSlava Imameev		echo "selftests: $TESTNAME [FAILED]"
64*f8b19aecSSlava Imameev	fi
65*f8b19aecSSlava Imameev	_cleanup
66*f8b19aecSSlava Imameev}
67*f8b19aecSSlava Imameev
68*f8b19aecSSlava Imameevcheck_root_privileges() {
69*f8b19aecSSlava Imameev	if [ $(id -u) -ne 0 ]; then
70*f8b19aecSSlava Imameev		echo "Need root privileges"
71*f8b19aecSSlava Imameev		exit $ksft_skip
72*f8b19aecSSlava Imameev	fi
73*f8b19aecSSlava Imameev}
74*f8b19aecSSlava Imameev
75*f8b19aecSSlava Imameev# Function to verify bpftool path.
76*f8b19aecSSlava Imameev# Parameters:
77*f8b19aecSSlava Imameev#   $1: bpftool path
78*f8b19aecSSlava Imameevverify_bpftool_path() {
79*f8b19aecSSlava Imameev	local bpftool_path="$1"
80*f8b19aecSSlava Imameev	if ! "$bpftool_path" version > /dev/null 2>&1; then
81*f8b19aecSSlava Imameev		echo "Could not run test without bpftool"
82*f8b19aecSSlava Imameev		exit $ksft_skip
83*f8b19aecSSlava Imameev	fi
84*f8b19aecSSlava Imameev}
85*f8b19aecSSlava Imameev
86*f8b19aecSSlava Imameev# Function to verify BTF support.
87*f8b19aecSSlava Imameev# The test requires BTF support for fmod_ret programs.
88*f8b19aecSSlava Imameevverify_btf_support() {
89*f8b19aecSSlava Imameev	if [ ! -f /sys/kernel/btf/vmlinux ]; then
90*f8b19aecSSlava Imameev		echo "Could not run test without BTF support"
91*f8b19aecSSlava Imameev		exit $ksft_skip
92*f8b19aecSSlava Imameev	fi
93*f8b19aecSSlava Imameev}
94*f8b19aecSSlava Imameev
95*f8b19aecSSlava Imameev# Function to initialize map entries with keys [0..2] and values set to 0.
96*f8b19aecSSlava Imameev# Parameters:
97*f8b19aecSSlava Imameev#  $1: Map name
98*f8b19aecSSlava Imameev#  $2: bpftool path
99*f8b19aecSSlava Imameevinitialize_map_entries() {
100*f8b19aecSSlava Imameev	local map_name="$1"
101*f8b19aecSSlava Imameev	local bpftool_path="$2"
102*f8b19aecSSlava Imameev
103*f8b19aecSSlava Imameev	for key in 0 1 2; do
104*f8b19aecSSlava Imameev		"$bpftool_path" map update name "$map_name" key $key 0 0 0 value 0 0 0 $key
105*f8b19aecSSlava Imameev	done
106*f8b19aecSSlava Imameev}
107*f8b19aecSSlava Imameev
108*f8b19aecSSlava Imameev# Test read access to the map.
109*f8b19aecSSlava Imameev# Parameters:
110*f8b19aecSSlava Imameev#   $1: Name command (name/pinned)
111*f8b19aecSSlava Imameev#   $2: Map name
112*f8b19aecSSlava Imameev#   $3: bpftool path
113*f8b19aecSSlava Imameev#   $4: key
114*f8b19aecSSlava Imameevaccess_for_read() {
115*f8b19aecSSlava Imameev	local name_cmd="$1"
116*f8b19aecSSlava Imameev	local map_name="$2"
117*f8b19aecSSlava Imameev	local bpftool_path="$3"
118*f8b19aecSSlava Imameev	local key="$4"
119*f8b19aecSSlava Imameev
120*f8b19aecSSlava Imameev	# Test read access to the map.
121*f8b19aecSSlava Imameev	if ! "$bpftool_path" map lookup "$name_cmd" "$map_name" key $key 1>/dev/null; then
122*f8b19aecSSlava Imameev		echo " Read access to $key in $map_name failed"
123*f8b19aecSSlava Imameev		exit 1
124*f8b19aecSSlava Imameev	fi
125*f8b19aecSSlava Imameev
126*f8b19aecSSlava Imameev	# Test read access to map's BTF data.
127*f8b19aecSSlava Imameev	if ! "$bpftool_path" btf dump map "$name_cmd" "$map_name" 1>/dev/null; then
128*f8b19aecSSlava Imameev		echo " Read access to $map_name for BTF data failed"
129*f8b19aecSSlava Imameev		exit 1
130*f8b19aecSSlava Imameev	fi
131*f8b19aecSSlava Imameev}
132*f8b19aecSSlava Imameev
133*f8b19aecSSlava Imameev# Test write access to the map.
134*f8b19aecSSlava Imameev# Parameters:
135*f8b19aecSSlava Imameev#   $1: Name command (name/pinned)
136*f8b19aecSSlava Imameev#   $2: Map name
137*f8b19aecSSlava Imameev#   $3: bpftool path
138*f8b19aecSSlava Imameev#   $4: key
139*f8b19aecSSlava Imameev#   $5: Whether write should succeed (true/false)
140*f8b19aecSSlava Imameevaccess_for_write() {
141*f8b19aecSSlava Imameev	local name_cmd="$1"
142*f8b19aecSSlava Imameev	local map_name="$2"
143*f8b19aecSSlava Imameev	local bpftool_path="$3"
144*f8b19aecSSlava Imameev	local key="$4"
145*f8b19aecSSlava Imameev	local write_should_succeed="$5"
146*f8b19aecSSlava Imameev	local value="1 1 1 1"
147*f8b19aecSSlava Imameev
148*f8b19aecSSlava Imameev	if "$bpftool_path" map update "$name_cmd" "$map_name" key $key value \
149*f8b19aecSSlava Imameev			$value 2>/dev/null; then
150*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "false" ]; then
151*f8b19aecSSlava Imameev			echo " Write access to $key in $map_name succeeded but should have failed"
152*f8b19aecSSlava Imameev			exit 1
153*f8b19aecSSlava Imameev		fi
154*f8b19aecSSlava Imameev	else
155*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "true" ]; then
156*f8b19aecSSlava Imameev			echo " Write access to $key in $map_name failed but should have succeeded"
157*f8b19aecSSlava Imameev			exit 1
158*f8b19aecSSlava Imameev		fi
159*f8b19aecSSlava Imameev	fi
160*f8b19aecSSlava Imameev}
161*f8b19aecSSlava Imameev
162*f8b19aecSSlava Imameev# Test entry deletion for the map.
163*f8b19aecSSlava Imameev# Parameters:
164*f8b19aecSSlava Imameev#   $1: Name command (name/pinned)
165*f8b19aecSSlava Imameev#   $2: Map name
166*f8b19aecSSlava Imameev#   $3: bpftool path
167*f8b19aecSSlava Imameev#   $4: key
168*f8b19aecSSlava Imameev#   $5: Whether write should succeed (true/false)
169*f8b19aecSSlava Imameevaccess_for_deletion() {
170*f8b19aecSSlava Imameev	local name_cmd="$1"
171*f8b19aecSSlava Imameev	local map_name="$2"
172*f8b19aecSSlava Imameev	local bpftool_path="$3"
173*f8b19aecSSlava Imameev	local key="$4"
174*f8b19aecSSlava Imameev	local write_should_succeed="$5"
175*f8b19aecSSlava Imameev	local value="1 1 1 1"
176*f8b19aecSSlava Imameev
177*f8b19aecSSlava Imameev	# Test deletion by key for the map.
178*f8b19aecSSlava Imameev	# Before deleting, check the key exists.
179*f8b19aecSSlava Imameev	if ! "$bpftool_path" map lookup "$name_cmd" "$map_name" key $key 1>/dev/null; then
180*f8b19aecSSlava Imameev		echo " Key $key does not exist in $map_name"
181*f8b19aecSSlava Imameev		exit 1
182*f8b19aecSSlava Imameev	fi
183*f8b19aecSSlava Imameev
184*f8b19aecSSlava Imameev	# Delete by key.
185*f8b19aecSSlava Imameev	if "$bpftool_path" map delete "$name_cmd" "$map_name" key $key 2>/dev/null; then
186*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "false" ]; then
187*f8b19aecSSlava Imameev			echo " Deletion for $key in $map_name succeeded but should have failed"
188*f8b19aecSSlava Imameev			exit 1
189*f8b19aecSSlava Imameev		fi
190*f8b19aecSSlava Imameev	else
191*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "true" ]; then
192*f8b19aecSSlava Imameev			echo " Deletion for $key in $map_name failed but should have succeeded"
193*f8b19aecSSlava Imameev			exit 1
194*f8b19aecSSlava Imameev		fi
195*f8b19aecSSlava Imameev	fi
196*f8b19aecSSlava Imameev
197*f8b19aecSSlava Imameev	# After deleting, check the entry existence according to the expected status.
198*f8b19aecSSlava Imameev	if "$bpftool_path" map lookup "$name_cmd" "$map_name" key $key 1>/dev/null; then
199*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "true" ]; then
200*f8b19aecSSlava Imameev			echo " Key $key for $map_name was not deleted but should have been deleted"
201*f8b19aecSSlava Imameev			exit 1
202*f8b19aecSSlava Imameev		fi
203*f8b19aecSSlava Imameev	else
204*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "false" ]; then
205*f8b19aecSSlava Imameev			echo "Key $key for $map_name was deleted but should have not been deleted"
206*f8b19aecSSlava Imameev			exit 1
207*f8b19aecSSlava Imameev		fi
208*f8b19aecSSlava Imameev	fi
209*f8b19aecSSlava Imameev
210*f8b19aecSSlava Imameev	# Test creation of map's deleted entry, if deletion was successful.
211*f8b19aecSSlava Imameev	# Otherwise, the entry exists.
212*f8b19aecSSlava Imameev	if "$bpftool_path" map update "$name_cmd" "$map_name" key $key value \
213*f8b19aecSSlava Imameev				$value 2>/dev/null; then
214*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "false" ]; then
215*f8b19aecSSlava Imameev			echo " Write access to $key in $map_name succeeded after deletion attempt but should have failed"
216*f8b19aecSSlava Imameev			exit 1
217*f8b19aecSSlava Imameev		fi
218*f8b19aecSSlava Imameev	else
219*f8b19aecSSlava Imameev		if [ "$write_should_succeed" = "true" ]; then
220*f8b19aecSSlava Imameev			echo " Write access to $key in $map_name failed after deletion attempt but should have succeeded"
221*f8b19aecSSlava Imameev			exit 1
222*f8b19aecSSlava Imameev		fi
223*f8b19aecSSlava Imameev	fi
224*f8b19aecSSlava Imameev}
225*f8b19aecSSlava Imameev
226*f8b19aecSSlava Imameev# Test map elements iterator.
227*f8b19aecSSlava Imameev# Parameters:
228*f8b19aecSSlava Imameev#   $1: Name command (name/pinned)
229*f8b19aecSSlava Imameev#   $2: Map name
230*f8b19aecSSlava Imameev#   $3: bpftool path
231*f8b19aecSSlava Imameev#   $4: BPF_DIR
232*f8b19aecSSlava Imameev#   $5: bpf iterator object file path
233*f8b19aecSSlava Imameeviterate_map_elem() {
234*f8b19aecSSlava Imameev	local name_cmd="$1"
235*f8b19aecSSlava Imameev	local map_name="$2"
236*f8b19aecSSlava Imameev	local bpftool_path="$3"
237*f8b19aecSSlava Imameev	local bpf_dir="$4"
238*f8b19aecSSlava Imameev	local bpf_file="$5"
239*f8b19aecSSlava Imameev	local pin_path="$bpf_dir/map_iterator"
240*f8b19aecSSlava Imameev
241*f8b19aecSSlava Imameev	"$bpftool_path" iter pin "$bpf_file" "$pin_path" map "$name_cmd" "$map_name"
242*f8b19aecSSlava Imameev	if [ ! -f "$pin_path" ]; then
243*f8b19aecSSlava Imameev		echo " Failed to pin iterator to $pin_path"
244*f8b19aecSSlava Imameev		exit 1
245*f8b19aecSSlava Imameev	fi
246*f8b19aecSSlava Imameev
247*f8b19aecSSlava Imameev	cat "$pin_path" 1>/dev/null
248*f8b19aecSSlava Imameev	rm "$pin_path" 2>/dev/null
249*f8b19aecSSlava Imameev}
250*f8b19aecSSlava Imameev
251*f8b19aecSSlava Imameev# Function to test map access with configurable write expectations
252*f8b19aecSSlava Imameev# Parameters:
253*f8b19aecSSlava Imameev#   $1: Name command (name/pinned)
254*f8b19aecSSlava Imameev#   $2: Map name
255*f8b19aecSSlava Imameev#   $3: bpftool path
256*f8b19aecSSlava Imameev#   $4: key for rw
257*f8b19aecSSlava Imameev#   $5: key to delete
258*f8b19aecSSlava Imameev#   $6: Whether write should succeed (true/false)
259*f8b19aecSSlava Imameev#   $7: BPF_DIR
260*f8b19aecSSlava Imameev#   $8: bpf iterator object file path
261*f8b19aecSSlava Imameevaccess_map() {
262*f8b19aecSSlava Imameev	local name_cmd="$1"
263*f8b19aecSSlava Imameev	local map_name="$2"
264*f8b19aecSSlava Imameev	local bpftool_path="$3"
265*f8b19aecSSlava Imameev	local key_for_rw="$4"
266*f8b19aecSSlava Imameev	local key_to_del="$5"
267*f8b19aecSSlava Imameev	local write_should_succeed="$6"
268*f8b19aecSSlava Imameev	local bpf_dir="$7"
269*f8b19aecSSlava Imameev	local bpf_iter_file_path="$8"
270*f8b19aecSSlava Imameev
271*f8b19aecSSlava Imameev	access_for_read "$name_cmd" "$map_name" "$bpftool_path" "$key_for_rw"
272*f8b19aecSSlava Imameev	access_for_write "$name_cmd" "$map_name" "$bpftool_path" "$key_for_rw" \
273*f8b19aecSSlava Imameev		"$write_should_succeed"
274*f8b19aecSSlava Imameev	access_for_deletion "$name_cmd" "$map_name" "$bpftool_path" "$key_to_del" \
275*f8b19aecSSlava Imameev		"$write_should_succeed"
276*f8b19aecSSlava Imameev	iterate_map_elem "$name_cmd" "$map_name" "$bpftool_path" "$bpf_dir" \
277*f8b19aecSSlava Imameev		"$bpf_iter_file_path"
278*f8b19aecSSlava Imameev}
279*f8b19aecSSlava Imameev
280*f8b19aecSSlava Imameev# Function to test map access with configurable write expectations
281*f8b19aecSSlava Imameev# Parameters:
282*f8b19aecSSlava Imameev#   $1: Map name
283*f8b19aecSSlava Imameev#   $2: bpftool path
284*f8b19aecSSlava Imameev#   $3: BPF_DIR
285*f8b19aecSSlava Imameev#   $4: Whether write should succeed (true/false)
286*f8b19aecSSlava Imameev#   $5: bpf iterator object file path
287*f8b19aecSSlava Imameevtest_map_access() {
288*f8b19aecSSlava Imameev	local map_name="$1"
289*f8b19aecSSlava Imameev	local bpftool_path="$2"
290*f8b19aecSSlava Imameev	local bpf_dir="$3"
291*f8b19aecSSlava Imameev	local pin_path="$bpf_dir/${map_name}_pinned"
292*f8b19aecSSlava Imameev	local write_should_succeed="$4"
293*f8b19aecSSlava Imameev	local bpf_iter_file_path="$5"
294*f8b19aecSSlava Imameev
295*f8b19aecSSlava Imameev	# Test access to the map by name.
296*f8b19aecSSlava Imameev	access_map "name" "$map_name" "$bpftool_path" "0 0 0 0" "1 0 0 0" \
297*f8b19aecSSlava Imameev		"$write_should_succeed" "$bpf_dir" "$bpf_iter_file_path"
298*f8b19aecSSlava Imameev
299*f8b19aecSSlava Imameev	# Pin the map to the BPF filesystem
300*f8b19aecSSlava Imameev	"$bpftool_path" map pin name "$map_name" "$pin_path"
301*f8b19aecSSlava Imameev	if [ ! -e "$pin_path" ]; then
302*f8b19aecSSlava Imameev		echo " Failed to pin $map_name"
303*f8b19aecSSlava Imameev		exit 1
304*f8b19aecSSlava Imameev	fi
305*f8b19aecSSlava Imameev
306*f8b19aecSSlava Imameev	# Test access to the pinned map.
307*f8b19aecSSlava Imameev	access_map "pinned" "$pin_path" "$bpftool_path" "0 0 0 0" "2 0 0 0" \
308*f8b19aecSSlava Imameev		"$write_should_succeed" "$bpf_dir" "$bpf_iter_file_path"
309*f8b19aecSSlava Imameev}
310*f8b19aecSSlava Imameev
311*f8b19aecSSlava Imameev# Function to test map creation and map-of-maps
312*f8b19aecSSlava Imameev# Parameters:
313*f8b19aecSSlava Imameev#   $1: bpftool path
314*f8b19aecSSlava Imameev#   $2: BPF_DIR
315*f8b19aecSSlava Imameevtest_map_creation_and_map_of_maps() {
316*f8b19aecSSlava Imameev	local bpftool_path="$1"
317*f8b19aecSSlava Imameev	local bpf_dir="$2"
318*f8b19aecSSlava Imameev	local outer_map_name="outer_map_tt"
319*f8b19aecSSlava Imameev	local inner_map_name="inner_map_tt"
320*f8b19aecSSlava Imameev
321*f8b19aecSSlava Imameev	"$bpftool_path" map create "$bpf_dir/$inner_map_name" type array key 4 \
322*f8b19aecSSlava Imameev		value 4 entries 4 name "$inner_map_name"
323*f8b19aecSSlava Imameev	if [ ! -f "$bpf_dir/$inner_map_name" ]; then
324*f8b19aecSSlava Imameev		echo " Failed to create inner map file at $bpf_dir/$outer_map_name"
325*f8b19aecSSlava Imameev		return 1
326*f8b19aecSSlava Imameev	fi
327*f8b19aecSSlava Imameev
328*f8b19aecSSlava Imameev	"$bpftool_path" map create "$bpf_dir/$outer_map_name" type hash_of_maps \
329*f8b19aecSSlava Imameev		key 4 value 4 entries 2 name "$outer_map_name" inner_map name "$inner_map_name"
330*f8b19aecSSlava Imameev	if [ ! -f "$bpf_dir/$outer_map_name" ]; then
331*f8b19aecSSlava Imameev		echo " Failed to create outer map file at $bpf_dir/$outer_map_name"
332*f8b19aecSSlava Imameev		return 1
333*f8b19aecSSlava Imameev	fi
334*f8b19aecSSlava Imameev
335*f8b19aecSSlava Imameev	# Add entries to the outer map by name and by pinned path.
336*f8b19aecSSlava Imameev	"$bpftool_path" map update pinned "$bpf_dir/$outer_map_name" key 0 0 0 0 \
337*f8b19aecSSlava Imameev		value pinned "$bpf_dir/$inner_map_name"
338*f8b19aecSSlava Imameev	"$bpftool_path" map update name "$outer_map_name" key 1 0 0 0 value \
339*f8b19aecSSlava Imameev		name "$inner_map_name"
340*f8b19aecSSlava Imameev
341*f8b19aecSSlava Imameev	# The outer map should be full by now.
342*f8b19aecSSlava Imameev	# The following map update command is expected to fail.
343*f8b19aecSSlava Imameev	if "$bpftool_path" map update name "$outer_map_name" key 2 0 0 0 value name \
344*f8b19aecSSlava Imameev		"$inner_map_name" 2>/dev/null; then
345*f8b19aecSSlava Imameev		echo " Update for $outer_map_name succeeded but should have failed"
346*f8b19aecSSlava Imameev		exit 1
347*f8b19aecSSlava Imameev	fi
348*f8b19aecSSlava Imameev}
349*f8b19aecSSlava Imameev
350*f8b19aecSSlava Imameev# Function to test map access with the btf list command
351*f8b19aecSSlava Imameev# Parameters:
352*f8b19aecSSlava Imameev#   $1: bpftool path
353*f8b19aecSSlava Imameevtest_map_access_with_btf_list() {
354*f8b19aecSSlava Imameev	local bpftool_path="$1"
355*f8b19aecSSlava Imameev
356*f8b19aecSSlava Imameev	# The btf list command iterates over maps for
357*f8b19aecSSlava Imameev	# loaded BPF programs.
358*f8b19aecSSlava Imameev	if ! "$bpftool_path" btf list 1>/dev/null; then
359*f8b19aecSSlava Imameev		echo " Failed to access btf data"
360*f8b19aecSSlava Imameev		exit 1
361*f8b19aecSSlava Imameev	fi
362*f8b19aecSSlava Imameev}
363*f8b19aecSSlava Imameev
364*f8b19aecSSlava Imameevset -eu
365*f8b19aecSSlava Imameev
366*f8b19aecSSlava Imameevtrap cleanup_skip EXIT
367*f8b19aecSSlava Imameev
368*f8b19aecSSlava Imameevcheck_root_privileges
369*f8b19aecSSlava Imameev
370*f8b19aecSSlava Imameevverify_bpftool_path "$BPFTOOL_PATH"
371*f8b19aecSSlava Imameev
372*f8b19aecSSlava Imameevverify_btf_support
373*f8b19aecSSlava Imameev
374*f8b19aecSSlava Imameevtrap cleanup EXIT
375*f8b19aecSSlava Imameev
376*f8b19aecSSlava Imameev# Load and attach the BPF programs to control maps access.
377*f8b19aecSSlava Imameev"$BPFTOOL_PATH" prog loadall "$BPF_FILE_PATH" "$BPF_DIR" autoattach
378*f8b19aecSSlava Imameev
379*f8b19aecSSlava Imameevinitialize_map_entries "$PROTECTED_MAP_NAME" "$BPFTOOL_PATH"
380*f8b19aecSSlava Imameevinitialize_map_entries "$NOT_PROTECTED_MAP_NAME" "$BPFTOOL_PATH"
381*f8b19aecSSlava Imameev
382*f8b19aecSSlava Imameev# Activate the map protection mechanism. Protection status is controlled
383*f8b19aecSSlava Imameev# by a value stored in the prot_status_map at index 0.
384*f8b19aecSSlava Imameev"$BPFTOOL_PATH" map update name prot_status_map key 0 0 0 0 value 1 0 0 0
385*f8b19aecSSlava Imameev
386*f8b19aecSSlava Imameev# Test protected map (write should fail).
387*f8b19aecSSlava Imameevtest_map_access "$PROTECTED_MAP_NAME" "$BPFTOOL_PATH" "$BPF_DIR" "false" \
388*f8b19aecSSlava Imameev "$BPF_ITER_FILE_PATH"
389*f8b19aecSSlava Imameev
390*f8b19aecSSlava Imameev# Test not protected map (write should succeed).
391*f8b19aecSSlava Imameevtest_map_access "$NOT_PROTECTED_MAP_NAME" "$BPFTOOL_PATH" "$BPF_DIR" "true" \
392*f8b19aecSSlava Imameev "$BPF_ITER_FILE_PATH"
393*f8b19aecSSlava Imameev
394*f8b19aecSSlava Imameevtest_map_creation_and_map_of_maps "$BPFTOOL_PATH" "$BPF_DIR"
395*f8b19aecSSlava Imameev
396*f8b19aecSSlava Imameevtest_map_access_with_btf_list "$BPFTOOL_PATH"
397*f8b19aecSSlava Imameev
398*f8b19aecSSlava Imameevexit 0
399