[<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