| #!/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 |