lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20181129002248.241080-2-posk@google.com>
Date:   Wed, 28 Nov 2018 16:22:48 -0800
From:   Peter Oskolkov <posk@...gle.com>
To:     Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>, netdev@...r.kernel.org
Cc:     Peter Oskolkov <posk.devel@...il.com>,
        Peter Oskolkov <posk@...gle.com>
Subject: [PATCH bpf-next 2/2] selftests/bpf: add test_lwt_ip_encap selftest

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@...gle.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ