Netdev List
 help / color / mirror / Atom feed
From: John Fastabend <john.fastabend@gmail.com>
To: alexei.starovoitov@gmail.com, daniel@iogearbox.net, davem@davemloft.net
Cc: netdev@vger.kernel.org
Subject: [RFC PATCH 15/16] bpf: verifier, simple loop examples
Date: Fri, 01 Jun 2018 02:33:34 -0700	[thread overview]
Message-ID: <20180601093334.15353.56867.stgit@john-Precision-Tower-5810> (raw)
In-Reply-To: <20180601092646.15353.28269.stgit@john-Precision-Tower-5810>

Add some simple loop examples. For now I just load these
using bpftool but eventually they should have a loader
simliar to test_verifier except for C snippets.

We want to use C files here instead of BPF because most
users will be using C clang/llvm and want to test how
well this works with the code generated by the actual
tools instead of hand-crafted BPF.
---
 tools/testing/selftests/bpf/Makefile           |    5 ++
 tools/testing/selftests/bpf/test_bad_loop1.c   |   47 ++++++++++++++++++++++
 tools/testing/selftests/bpf/test_bad_loop2.c   |   45 +++++++++++++++++++++
 tools/testing/selftests/bpf/test_bad_loop3.c   |   47 ++++++++++++++++++++++
 tools/testing/selftests/bpf/test_basic_loop1.c |   44 +++++++++++++++++++++
 tools/testing/selftests/bpf/test_basic_loop2.c |   48 +++++++++++++++++++++++
 tools/testing/selftests/bpf/test_basic_loop3.c |   51 ++++++++++++++++++++++++
 7 files changed, 286 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/bpf/test_bad_loop1.c
 create mode 100644 tools/testing/selftests/bpf/test_bad_loop2.c
 create mode 100644 tools/testing/selftests/bpf/test_bad_loop3.c
 create mode 100644 tools/testing/selftests/bpf/test_basic_loop1.c
 create mode 100644 tools/testing/selftests/bpf/test_basic_loop2.c
 create mode 100644 tools/testing/selftests/bpf/test_basic_loop3.c

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index a1b66da..0cf7bd1 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -34,7 +34,10 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
 	sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \
 	test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \
 	test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
-	test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o
+	test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o \
+	test_basic_loop1.o test_basic_loop2.o test_basic_loop3.o \
+	test_bad_loop1.o test_bad_loop2.o test_bad_loop3.o
+
 
 # Order correspond to 'make run_tests' order
 TEST_PROGS := test_kmod.sh \
diff --git a/tools/testing/selftests/bpf/test_bad_loop1.c b/tools/testing/selftests/bpf/test_bad_loop1.c
new file mode 100644
index 0000000..88e8cfb
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_bad_loop1.c
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+
+/* Test packet access out of bounds */
+
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	 __u8 i = 0, j = 0, k = 0, *p;
+
+	 p = data;
+	 if (data + 50 > data_end)
+		 return TC_ACT_OK;
+
+#pragma nounroll
+	while (i < 100) {
+		k += p[i];
+		p[i] = k;
+		i++;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_bad_loop2.c b/tools/testing/selftests/bpf/test_bad_loop2.c
new file mode 100644
index 0000000..fff005e
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_bad_loop2.c
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+/* Test non-terminating loops */
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	int i = 0, j = 0, k = 0, *p;
+
+	 p = data;
+	 if (data + 101 > data_end)
+		 return TC_ACT_OK;
+
+#pragma nounroll
+	while (i < 100) {
+		k += p[i];
+		p[i] = k;
+		i--;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_bad_loop3.c b/tools/testing/selftests/bpf/test_bad_loop3.c
new file mode 100644
index 0000000..4015366
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_bad_loop3.c
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	 __u8 i = 0, j = 0, k = 0, *p;
+
+	 p = data;
+	 if (data + 101 > data_end)
+		 return TC_ACT_OK;
+
+head:
+#pragma nounroll
+	while (i < 100) {
+		k += p[i];
+		p[i] = k;
+		i++;
+		if (k < 100)
+			goto head;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_basic_loop1.c b/tools/testing/selftests/bpf/test_basic_loop1.c
new file mode 100644
index 0000000..63dc4a4
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_basic_loop1.c
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	 __u8 i = 0, j = 0, k = 0, *p;
+
+	 p = data;
+	 if (data + 101 > data_end)
+		 return TC_ACT_OK;
+
+#pragma nounroll
+	while (i < 100) {
+		k += p[i];
+		p[i] = k;
+		i++;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_basic_loop2.c b/tools/testing/selftests/bpf/test_basic_loop2.c
new file mode 100644
index 0000000..fb774dc
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_basic_loop2.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	 __u8 i = 0, j = 0, k = 0, *p;
+
+	 p = data;
+	 if (data + 101 > data_end)
+		 return TC_ACT_OK;
+
+#pragma nounroll
+	while (i < 100) {
+		k += p[i];
+		if (k < 100) {
+			p[i] = 'a';
+		} else {
+			p[i] = 'b';
+		}
+		i++;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_basic_loop3.c b/tools/testing/selftests/bpf/test_basic_loop3.c
new file mode 100644
index 0000000..dd7dd1b
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_basic_loop3.c
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Covalent IO
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include "bpf_helpers.h"
+#include "test_iptunnel_common.h"
+#include "bpf_endian.h"
+
+int _version SEC("version") = 1;
+SEC("classifier_tc_loop1")
+int _tc_loop(struct __sk_buff *ctx)
+{
+	void *data      = (void *)(unsigned long)ctx->data;
+	void *data_end  = (void *)(unsigned long)ctx->data_end;
+	 __u8 i = 0, j = 0, k = 0, *p;
+
+	 if (data + 2 > data_end)
+		 return TC_ACT_OK;
+
+	 p = data;
+	 j = p[0];
+
+	 if (data + 101 > data_end)
+		 return TC_ACT_OK;
+
+	 if (j < 100)
+		 return TC_ACT_OK;
+
+#pragma nounroll
+	while (i < j) {
+		k += p[i];
+		i++;
+	}
+	ctx->mark = k;
+
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";

  parent reply	other threads:[~2018-06-01  9:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-01  9:32 [RFC PATCH 00/16] bpf, bounded loop support work in progress John Fastabend
2018-06-01  9:32 ` [RFC PATCH 01/16] bpf: cfg: partition basic blocks for each subprog John Fastabend
2018-06-01  9:32 ` [RFC PATCH 02/16] bpf: cfg: add edges between basic blocks to form CFG John Fastabend
2018-06-01  9:32 ` [RFC PATCH 03/16] bpf: cfg: build domination tree using Tarjan algorithm John Fastabend
2018-06-01  9:32 ` [RFC PATCH 04/16] bpf: cfg: detect loop use domination information John Fastabend
2018-06-01  9:32 ` [RFC PATCH 05/16] bpf: cfg: detect unreachable basic blocks John Fastabend
2018-06-01  9:32 ` [RFC PATCH 06/16] bpf: cfg: move find_subprog/add_subprog to cfg.c John Fastabend
2018-06-01  9:32 ` [RFC PATCH 07/16] bpf: cfg: build call graph and detect unreachable/recursive call John Fastabend
2018-06-01  9:32 ` [RFC PATCH 08/16] bpf: cfg: remove push_insn and check_cfg John Fastabend
2018-06-01  9:33 ` [RFC PATCH 09/16] bpf: cfg: reduce k*alloc/free call by using memory pool for allocating nodes John Fastabend
2018-06-01  9:33 ` [RFC PATCH 10/16] bpf: cfg: reduce memory usage by using singly list + compat pointer John Fastabend
2018-06-01  9:33 ` [RFC PATCH 11/16] bpf: cfg: detect irreducible loop using Eric Stoltz algorithm John Fastabend
2018-06-01  9:33 ` [RFC PATCH 12/16] bpf: cfg: pretty print CFG and DOM John Fastabend
2018-06-01  9:33 ` [RFC PATCH 13/16] bpf: verifier, can ptr range be calculated with scalar ALU op John Fastabend
2018-06-01  9:33 ` [RFC PATCH 14/16] bpf: verifier, add initial support to allow bounded loops John Fastabend
2018-06-01  9:33 ` John Fastabend [this message]
2018-06-01  9:33 ` [RFC PATCH 16/16] bpf: tools: dbg patch to turn on debugging and add primitive examples John Fastabend

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=20180601093334.15353.56867.stgit@john-Precision-Tower-5810 \
    --to=john.fastabend@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox