summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/bpf/test_flow_dissector.sh
blob: 174b72a64a4c57f3fd65ba1c085238be25fac8f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Load BPF flow dissector and verify it correctly dissects traffic
export TESTNAME=test_flow_dissector
unmount=0

# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4

msg="skip all tests:"
if [ $UID != 0 ]; then
	echo $msg please run this as root >&2
	exit $ksft_skip
fi

# This test needs to be run in a network namespace with in_netns.sh. Check if
# this is the case and run it with in_netns.sh if it is being run in the root
# namespace.
if [[ -z $(ip netns identify $$) ]]; then
	err=0
	if bpftool="$(which bpftool)"; then
		echo "Testing global flow dissector..."

		$bpftool prog loadall ./bpf_flow.o /sys/fs/bpf/flow \
			type flow_dissector

		if ! unshare --net $bpftool prog attach pinned \
			/sys/fs/bpf/flow/flow_dissector flow_dissector; then
			echo "Unexpected unsuccessful attach in namespace" >&2
			err=1
		fi

		$bpftool prog attach pinned /sys/fs/bpf/flow/flow_dissector \
			flow_dissector

		if unshare --net $bpftool prog attach pinned \
			/sys/fs/bpf/flow/flow_dissector flow_dissector; then
			echo "Unexpected successful attach in namespace" >&2
			err=1
		fi

		if ! $bpftool prog detach pinned \
			/sys/fs/bpf/flow/flow_dissector flow_dissector; then
			echo "Failed to detach flow dissector" >&2
			err=1
		fi

		rm -rf /sys/fs/bpf/flow
	else
		echo "Skipping root flow dissector test, bpftool not found" >&2
	fi

	# Run the rest of the tests in a net namespace.
	../net/in_netns.sh "$0" "$@"
	err=$(( $err + $? ))

	if (( $err == 0 )); then
		echo "selftests: $TESTNAME [PASS]";
	else
		echo "selftests: $TESTNAME [FAILED]";
	fi

	exit $err
fi

# Determine selftest success via shell exit code
exit_handler()
{
	set +e

	# Cleanup
	tc filter del dev lo ingress pref 1337 2> /dev/null
	tc qdisc del dev lo ingress 2> /dev/null
	./flow_dissector_load -d 2> /dev/null
	if [ $unmount -ne 0 ]; then
		umount bpffs 2> /dev/null
	fi
}

# Exit script immediately (well catched by trap handler) if any
# program/thing exits with a non-zero status.
set -e

# (Use 'trap -l' to list meaning of numbers)
trap exit_handler 0 2 3 6 9

# Mount BPF file system
if /bin/mount | grep /sys/fs/bpf > /dev/null; then
	echo "bpffs already mounted"
else
	echo "bpffs not mounted. Mounting..."
	unmount=1
	/bin/mount bpffs /sys/fs/bpf -t bpf
fi

# Attach BPF program
./flow_dissector_load -p bpf_flow.o -s flow_dissector

# Setup
tc qdisc add dev lo ingress
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/lo/rp_filter

echo "Testing IPv4..."
# Drops all IP/UDP packets coming from port 9
tc filter add dev lo parent ffff: protocol ip pref 1337 flower ip_proto \
	udp src_port 9 action drop

# Send 10 IPv4/UDP packets from port 8. Filter should not drop any.
./test_flow_dissector -i 4 -f 8
# Send 10 IPv4/UDP packets from port 9. Filter should drop all.
./test_flow_dissector -i 4 -f 9 -F
# Send 10 IPv4/UDP packets from port 10. Filter should not drop any.
./test_flow_dissector -i 4 -f 10

echo "Testing IPIP..."
# Send 10 IPv4/IPv4/UDP packets from port 8. Filter should not drop any.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e bare -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 8
# Send 10 IPv4/IPv4/UDP packets from port 9. Filter should drop all.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e bare -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 9 -F
# Send 10 IPv4/IPv4/UDP packets from port 10. Filter should not drop any.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e bare -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 10

echo "Testing IPv4 + GRE..."
# Send 10 IPv4/GRE/IPv4/UDP packets from port 8. Filter should not drop any.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e gre -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 8
# Send 10 IPv4/GRE/IPv4/UDP packets from port 9. Filter should drop all.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e gre -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 9 -F
# Send 10 IPv4/GRE/IPv4/UDP packets from port 10. Filter should not drop any.
./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e gre -i 4 \
	-D 192.168.0.1 -S 1.1.1.1 -f 10

tc filter del dev lo ingress pref 1337

echo "Testing port range..."
# Drops all IP/UDP packets coming from port 8-10
tc filter add dev lo parent ffff: protocol ip pref 1337 flower ip_proto \
	udp src_port 8-10 action drop

# Send 10 IPv4/UDP packets from port 7. Filter should not drop any.
./test_flow_dissector -i 4 -f 7
# Send 10 IPv4/UDP packets from port 9. Filter should drop all.
./test_flow_dissector -i 4 -f 9 -F
# Send 10 IPv4/UDP packets from port 11. Filter should not drop any.
./test_flow_dissector -i 4 -f 11

tc filter del dev lo ingress pref 1337

echo "Testing IPv6..."
# Drops all IPv6/UDP packets coming from port 9
tc filter add dev lo parent ffff: protocol ipv6 pref 1337 flower ip_proto \
	udp src_port 9 action drop

# Send 10 IPv6/UDP packets from port 8. Filter should not drop any.
./test_flow_dissector -i 6 -f 8
# Send 10 IPv6/UDP packets from port 9. Filter should drop all.
./test_flow_dissector -i 6 -f 9 -F
# Send 10 IPv6/UDP packets from port 10. Filter should not drop any.
./test_flow_dissector -i 6 -f 10

exit 0