hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
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