All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Oskolkov <posk@google.com>
To: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	netdev@vger.kernel.org
Cc: Peter Oskolkov <posk.devel@gmail.com>, Peter Oskolkov <posk@google.com>
Subject: [PATCH bpf-next 2/2] selftests/bpf: add test_lwt_ip_encap selftest
Date: Wed, 28 Nov 2018 16:22:48 -0800	[thread overview]
Message-ID: <20181129002248.241080-2-posk@google.com> (raw)
In-Reply-To: <20181129002248.241080-1-posk@google.com>

This patch adds a sample/selftest that covers BPF_LWT_ENCAP_IP option
added in the first patch in the series.

Signed-off-by: Peter Oskolkov <posk@google.com>
---
 tools/testing/selftests/bpf/Makefile          |   5 +-
 .../testing/selftests/bpf/test_lwt_ip_encap.c |  65 ++++++++++
 .../selftests/bpf/test_lwt_ip_encap.sh        | 114 ++++++++++++++++++
 3 files changed, 182 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/test_lwt_ip_encap.c
 create mode 100755 tools/testing/selftests/bpf/test_lwt_ip_encap.sh

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 73aa6d8f4a2f..044fcdbc9864 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -39,7 +39,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
 	get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
 	test_skb_cgroup_id_kern.o bpf_flow.o netcnt_prog.o \
 	test_sk_lookup_kern.o test_xdp_vlan.o test_queue_map.o test_stack_map.o \
-	xdp_dummy.o test_map_in_map.o
+	xdp_dummy.o test_map_in_map.o test_lwt_ip_encap.o
 
 # Order correspond to 'make run_tests' order
 TEST_PROGS := test_kmod.sh \
@@ -53,7 +53,8 @@ TEST_PROGS := test_kmod.sh \
 	test_lirc_mode2.sh \
 	test_skb_cgroup_id.sh \
 	test_flow_dissector.sh \
-	test_xdp_vlan.sh
+	test_xdp_vlan.sh \
+	test_lwt_ip_encap.sh
 
 TEST_PROGS_EXTENDED := with_addr.sh
 
diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.c b/tools/testing/selftests/bpf/test_lwt_ip_encap.c
new file mode 100644
index 000000000000..967db922dcc6
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <string.h>
+#include "bpf_helpers.h"
+#include "bpf_endian.h"
+
+#define BPF_LWT_ENCAP_IP 2
+
+struct iphdr {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	__u8	ihl:4,
+		version:4;
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+	__u8	version:4,
+		ihl:4;
+#else
+#error "Fix your compiler's __BYTE_ORDER__?!"
+#endif
+	__u8	tos;
+	__be16	tot_len;
+	__be16	id;
+	__be16	frag_off;
+	__u8	ttl;
+	__u8	protocol;
+	__sum16	check;
+	__be32	saddr;
+	__be32	daddr;
+};
+
+struct grehdr {
+	__be16 flags;
+	__be16 protocol;
+};
+
+SEC("encap_gre")
+int bpf_lwt_encap_gre(struct __sk_buff *skb)
+{
+	char encap_header[24];
+	int err;
+	struct iphdr *iphdr = (struct iphdr *)encap_header;
+	struct grehdr *greh = (struct grehdr *)(encap_header + sizeof(struct iphdr));
+
+	memset(encap_header, 0, sizeof(encap_header));
+
+	iphdr->ihl = 5;
+	iphdr->version = 4;
+	iphdr->tos = 0;
+	iphdr->ttl = 0x40;
+	iphdr->protocol = 47;  /* IPPROTO_GRE */
+	iphdr->saddr = 0x640110ac;  /* 172.16.1.100 */
+	iphdr->daddr = 0x640310ac;  /* 172.16.5.100 */
+	iphdr->check = 0;
+	iphdr->tot_len = bpf_htons(skb->len + sizeof(encap_header));
+
+	greh->protocol = bpf_htons(0x800);
+
+	err = bpf_lwt_push_encap(skb, BPF_LWT_ENCAP_IP, (void *)encap_header,
+				 sizeof(encap_header));
+	if (err)
+		return BPF_DROP;
+
+	return BPF_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh
new file mode 100755
index 000000000000..4c32b754bf96
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Setup:
+# - create VETH1/VETH2 veth
+# - VETH1 gets IP_SRC
+# - create netns NS
+# - move VETH2 to NS, add IP_DST
+# - in NS, create gre tunnel GREDEV, add IP_GRE
+# - in NS, configure GREDEV to route to IP_DST from IP_SRC
+# - configure route to IP_GRE via VETH1
+#   (note: there is no route to IP_DST from root/init ns)
+#
+# Test:
+# - listen on IP_DST
+# - send a packet to IP_DST: the listener does not get it
+# - add LWT_XMIT bpf to IP_DST that gre-encaps all packets to IP_GRE
+# - send a packet to IP_DST: the listener gets it
+
+
+# set -x  # debug ON
+set +x  # debug OFF
+set -e  # exit on error
+
+if [[ $EUID -ne 0 ]]; then
+	echo "This script must be run as root"
+	echo "FAIL"
+	exit 1
+fi
+
+readonly NS="ns-ip-encap-$(mktemp -u XXXXXX)"
+readonly OUT=$(mktemp /tmp/test_lwt_ip_incap.XXXXXX)
+
+readonly NET_SRC="172.16.1.0"
+
+readonly IP_SRC="172.16.1.100"
+readonly IP_DST="172.16.2.100"
+readonly IP_GRE="172.16.3.100"
+
+readonly PORT=5555
+readonly MSG="foo_bar"
+
+PID1=0
+PID2=0
+
+setup() {
+	ip link add veth1 type veth peer name veth2
+
+	ip netns add "${NS}"
+	ip link set veth2 netns ${NS}
+
+	ip link set dev veth1 up
+	ip -netns ${NS} link set dev veth2 up
+
+	ip addr add dev veth1 ${IP_SRC}/24
+	ip -netns ${NS} addr add dev veth2 ${IP_DST}/24
+
+	ip -netns ${NS} tunnel add gre_dev mode gre remote ${IP_SRC} local ${IP_GRE} ttl 255
+	ip -netns ${NS} link set gre_dev up
+	ip -netns ${NS} addr add ${IP_GRE} dev gre_dev
+	ip -netns ${NS} route add ${NET_SRC}/24 dev gre_dev
+
+	ip route add ${IP_GRE}/32 dev veth1
+}
+
+cleanup() {
+	ip link del veth1
+	ip netns del ${NS}
+	if [ $PID1 -ne 0 ] ; then kill $PID1 ; fi
+	if [ $PID2 -ne 0 ] ; then kill $PID2 ; fi
+	rm $OUT
+}
+
+trap cleanup EXIT
+setup
+
+# start the listener
+ip netns exec ${NS} nc -ul ${IP_DST} $PORT > $OUT &
+PID1=$!
+usleep 100000
+
+# send a packet
+echo -ne "${MSG}" | nc -u ${IP_DST} $PORT &
+PID2=$!
+usleep 1000000
+kill $PID2
+PID2=0
+
+# confirm the packet was not delivered
+if [ "$(<$OUT)" != "" ]; then
+	echo "FAIL: unexpected packet"
+	exit 1
+fi
+
+# install an lwt/bpf encap prog
+ip route add ${IP_DST} encap bpf xmit obj test_lwt_ip_encap.o sec encap_gre dev veth1
+usleep 100000
+
+# send a packet
+echo -ne "${MSG}" | nc -u ${IP_DST} $PORT &
+PID2=$!
+usleep 1000000
+kill $PID2
+PID2=0
+kill $PID1
+PID1=0
+
+if [ "$(<$OUT)" != "$MSG" ]; then
+	echo "FAIL"
+	exit 1
+fi
+
+echo "PASS"
+
-- 
2.20.0.rc0.387.gc7a69e6b6c-goog

  reply	other threads:[~2018-11-29 11:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-29  0:22 [PATCH bpf-next 1/2] bpf: add BPF_LWT_ENCAP_IP option to bpf_lwt_push_encap Peter Oskolkov
2018-11-29  0:22 ` Peter Oskolkov [this message]
2018-11-29  0:47 ` David Ahern
2018-11-29  1:34   ` Peter Oskolkov
2018-11-30 20:08     ` David Ahern
2018-11-30 23:35       ` Peter Oskolkov
2018-11-30 23:51         ` David Ahern
2018-12-01  0:14           ` Peter Oskolkov
2018-12-03 16:04             ` David Ahern
2018-12-03 16:55               ` Peter Oskolkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181129002248.241080-2-posk@google.com \
    --to=posk@google.com \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=netdev@vger.kernel.org \
    --cc=posk.devel@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.