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";

Reply via email to