diff mbox series

[v3,bpf-next,13/15] selftest: Add test for xdp_egress

Message ID 20200424201428.89514-14-dsahern@kernel.org
State Changes Requested
Delegated to: BPF Maintainers
Headers show
Series net: Add support for XDP in egress path | expand

Commit Message

David Ahern April 24, 2020, 8:14 p.m. UTC
From: David Ahern <dahern@digitalocean.com>

Add selftest for xdp_egress. Add xdp_drop program to veth connecting
a namespace to drop packets and break connectivity.

Signed-off-by: David Ahern <dahern@digitalocean.com>
---
 tools/testing/selftests/bpf/Makefile          |   1 +
 tools/testing/selftests/bpf/progs/xdp_drop.c  |  25 +++
 .../testing/selftests/bpf/test_xdp_egress.sh  | 160 ++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/xdp_drop.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_egress.sh

Comments

John Fastabend April 27, 2020, 5:48 p.m. UTC | #1
David Ahern wrote:
> From: David Ahern <dahern@digitalocean.com>
> 
> Add selftest for xdp_egress. Add xdp_drop program to veth connecting
> a namespace to drop packets and break connectivity.
> 
> Signed-off-by: David Ahern <dahern@digitalocean.com>
> ---

[...]

> +################################################################################
> +# main
> +
> +if [ $(id -u) -ne 0 ]; then
> +	echo "selftests: $TESTNAME [SKIP] Need root privileges"
> +	exit $ksft_skip
> +fi
> +
> +if ! ip link set dev lo xdp off > /dev/null 2>&1; then
> +	echo "selftests: $TESTNAME [SKIP] Could not run test without the ip xdp support"
> +	exit $ksft_skip
> +fi
> +
> +if [ -z "$BPF_FS" ]; then
> +	echo "selftests: $TESTNAME [SKIP] Could not run test without bpffs mounted"
> +	exit $ksft_skip
> +fi
> +
> +if ! bpftool version > /dev/null 2>&1; then
> +	echo "selftests: $TESTNAME [SKIP] Could not run test without bpftool"
> +	exit $ksft_skip
> +fi

This is consistent with test_xdp_veth.sh so it is probably ok for this series
but I think it would be nice to go back and make these fail on errors. Or at
least fail on bpffs mount. Seems other tests fail on bpffs mount failures so
would be OK I think.

Otherwise LGTM.
John Fastabend April 27, 2020, 5:52 p.m. UTC | #2
John Fastabend wrote:
> David Ahern wrote:
> > From: David Ahern <dahern@digitalocean.com>
> > 
> > Add selftest for xdp_egress. Add xdp_drop program to veth connecting
> > a namespace to drop packets and break connectivity.
> > 
> > Signed-off-by: David Ahern <dahern@digitalocean.com>
> > ---
> 
> [...]
> 
> > +################################################################################
> > +# main
> > +
> > +if [ $(id -u) -ne 0 ]; then
> > +	echo "selftests: $TESTNAME [SKIP] Need root privileges"
> > +	exit $ksft_skip
> > +fi
> > +
> > +if ! ip link set dev lo xdp off > /dev/null 2>&1; then
> > +	echo "selftests: $TESTNAME [SKIP] Could not run test without the ip xdp support"
> > +	exit $ksft_skip
> > +fi
> > +
> > +if [ -z "$BPF_FS" ]; then
> > +	echo "selftests: $TESTNAME [SKIP] Could not run test without bpffs mounted"
> > +	exit $ksft_skip
> > +fi
> > +
> > +if ! bpftool version > /dev/null 2>&1; then
> > +	echo "selftests: $TESTNAME [SKIP] Could not run test without bpftool"
> > +	exit $ksft_skip
> > +fi
> 
> This is consistent with test_xdp_veth.sh so it is probably ok for this series
> but I think it would be nice to go back and make these fail on errors. Or at
> least fail on bpffs mount. Seems other tests fail on bpffs mount failures so
> would be OK I think.
> 
> Otherwise LGTM.

Also would be nice to have a test case for the xdp redirect into tx case. I think
this is only going to test the skb path?

Thanks,
John
David Ahern April 27, 2020, 5:58 p.m. UTC | #3
On 4/27/20 11:52 AM, John Fastabend wrote:
> Also would be nice to have a test case for the xdp redirect into tx case. I think
> this is only going to test the skb path?

I have tests for the xdp_frame case, but it requires multiple nodes -
not namespaces. Multiple node tests no longer fall into the 'selftest'
category. I am not aware of any way to do XDP_REDIRECT testing within a
single node; general shortcoming with all xdp_frame specific tests.
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 7729892e0b04..5dae18ebac13 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -50,6 +50,7 @@  TEST_PROGS := test_kmod.sh \
 	test_xdp_redirect.sh \
 	test_xdp_meta.sh \
 	test_xdp_veth.sh \
+	test_xdp_egress.sh \
 	test_offload.py \
 	test_sock_addr.sh \
 	test_tunnel.sh \
diff --git a/tools/testing/selftests/bpf/progs/xdp_drop.c b/tools/testing/selftests/bpf/progs/xdp_drop.c
new file mode 100644
index 000000000000..cffabc53a5e1
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/xdp_drop.c
@@ -0,0 +1,25 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <linux/if_ether.h>
+#include <bpf/bpf_helpers.h>
+
+SEC("drop")
+int xdp_drop(struct xdp_md *ctx)
+{
+	void *data_end = (void *)(long)ctx->data_end;
+	void *data = (void *)(long)ctx->data;
+	struct ethhdr *eth = data;
+	void *nh;
+
+	nh = data + sizeof(*eth);
+	if (nh > data_end)
+		return XDP_DROP;
+
+	if (eth->h_proto == 0x0008)
+		return XDP_DROP;
+
+	return XDP_PASS;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_xdp_egress.sh b/tools/testing/selftests/bpf/test_xdp_egress.sh
new file mode 100755
index 000000000000..7efa59fdf823
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xdp_egress.sh
@@ -0,0 +1,160 @@ 
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# XDP egress tests.
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+TESTNAME=xdp_egress
+BPF_FS=$(awk '$3 == "bpf" {print $2; exit}' /proc/mounts)
+
+ret=0
+
+################################################################################
+#
+log_test()
+{
+	local rc=$1
+	local expected=$2
+	local msg="$3"
+
+	if [ ${rc} -eq ${expected} ]; then
+		printf "TEST: %-60s  [ OK ]\n" "${msg}"
+	else
+		ret=1
+		printf "TEST: %-60s  [FAIL]\n" "${msg}"
+	fi
+}
+
+################################################################################
+# create namespaces and connect them
+
+create_ns()
+{
+	local ns=$1
+	local addr=$2
+	local addr6=$3
+
+	ip netns add ${ns}
+
+	ip -netns ${ns} link set lo up
+	ip -netns ${ns} addr add dev lo ${addr}
+	ip -netns ${ns} -6 addr add dev lo ${addr6}
+
+	ip -netns ${ns} ro add unreachable default metric 8192
+	ip -netns ${ns} -6 ro add unreachable default metric 8192
+
+	ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1
+	ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
+	ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
+	ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
+	ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.accept_dad=0
+}
+
+connect_ns()
+{
+	local ns1=$1
+	local ns1_dev=$2
+	local ns1_addr=$3
+	local ns1_addr6=$4
+	local ns2=$5
+	local ns2_dev=$6
+	local ns2_addr=$7
+	local ns2_addr6=$8
+	local ns1arg
+	local ns2arg
+
+	if [ -n "${ns1}" ]; then
+		ns1arg="-netns ${ns1}"
+	fi
+	if [ -n "${ns2}" ]; then
+		ns2arg="-netns ${ns2}"
+	fi
+
+	ip ${ns1arg} li add ${ns1_dev} type veth peer name tmp
+	ip ${ns1arg} li set ${ns1_dev} up
+	ip ${ns1arg} li set tmp netns ${ns2} name ${ns2_dev}
+	ip ${ns2arg} li set ${ns2_dev} up
+
+	ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr}
+	ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr}
+
+	ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr6} nodad
+	ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr6} nodad
+}
+
+################################################################################
+#
+
+setup()
+{
+	create_ns host 172.16.101.1/32 2001:db8:101::1/128
+	connect_ns "" veth-host 172.16.1.1/24 2001:db8:1::1/64 host eth0 172.16.1.2/24 2001:db8:1::2/64
+	ip ro add 172.16.101.1 via 172.16.1.2
+	ip -6 ro add 2001:db8:101::1 via 2001:db8:1::2
+	ping -c1 -w1 172.16.101.1 >/dev/null 2>&1
+	ping -c1 -w1 2001:db8:101::1 >/dev/null 2>&1
+}
+
+cleanup()
+{
+	ip li del veth-host 2>/dev/null
+	ip netns del host 2>/dev/null
+	rm -f $BPF_FS/test_$TESTNAME
+}
+
+################################################################################
+# main
+
+if [ $(id -u) -ne 0 ]; then
+	echo "selftests: $TESTNAME [SKIP] Need root privileges"
+	exit $ksft_skip
+fi
+
+if ! ip link set dev lo xdp off > /dev/null 2>&1; then
+	echo "selftests: $TESTNAME [SKIP] Could not run test without the ip xdp support"
+	exit $ksft_skip
+fi
+
+if [ -z "$BPF_FS" ]; then
+	echo "selftests: $TESTNAME [SKIP] Could not run test without bpffs mounted"
+	exit $ksft_skip
+fi
+
+if ! bpftool version > /dev/null 2>&1; then
+	echo "selftests: $TESTNAME [SKIP] Could not run test without bpftool"
+	exit $ksft_skip
+fi
+
+cleanup
+trap cleanup EXIT
+
+set -e
+setup
+set +e
+
+bpftool prog load xdp_drop.o $BPF_FS/test_$TESTNAME type xdp_egress || exit 1
+ID=$(bpftool prog show name xdp_drop | awk '$4 == "xdp_drop" {print $1}')
+
+# attach egress program
+bpftool net attach xdp_egress id ${ID/:/} dev veth-host
+ping -c1 -w1 172.16.101.1 >/dev/null 2>&1
+log_test $? 1 "IPv4 connectivity disabled by xdp_egress"
+ping -c1 -w1 2001:db8:101::1 >/dev/null 2>&1
+log_test $? 0 "IPv6 connectivity not disabled by egress drop program"
+
+# detach program should restore connectivity
+bpftool net detach xdp_egress dev veth-host
+ping -c1 -w1 172.16.101.1 >/dev/null 2>&1
+log_test $? 0 "IPv4 connectivity restored"
+
+# cleanup on delete
+ip netns exec host bpftool net attach xdp_egress id ${ID/:/} dev eth0
+bpftool net attach xdp_egress id ${ID/:/} dev veth-host
+ip li del veth-host
+rm -f $BPF_FS/test_$TESTNAME
+sleep 5  # rcu grace pass; verify program is dropped
+bpftool prog show name xdp_drop
+
+exit $ret