selftests/bpf: Fix sk_assign on s390x
authorIlya Leoshkevich <iii@linux.ibm.com>
Sun, 29 Jan 2023 19:04:54 +0000 (20:04 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 30 Jan 2023 03:16:28 +0000 (19:16 -0800)
sk_assign is failing on an s390x machine running Debian "bookworm" for
2 reasons: legacy server_map definition and uninitialized addrlen in
recvfrom() call.

Fix by adding a new-style server_map definition and dropping addrlen
(recvfrom() allows NULL values for src_addr and addrlen).

Since the test should support tc built without libbpf, build the prog
twice: with the old-style definition and with the new-style definition,
then select the right one at runtime. This could be done at compile
time too, but this would not be cross-compilation friendly.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20230129190501.1624747-2-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/sk_assign.c
tools/testing/selftests/bpf/progs/test_sk_assign.c
tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c [new file with mode: 0644]

index 3e190ed..1374b62 100644 (file)
@@ -29,7 +29,23 @@ static int stop, duration;
 static bool
 configure_stack(void)
 {
+       char tc_version[128];
        char tc_cmd[BUFSIZ];
+       char *prog;
+       FILE *tc;
+
+       /* Check whether tc is built with libbpf. */
+       tc = popen("tc -V", "r");
+       if (CHECK_FAIL(!tc))
+               return false;
+       if (CHECK_FAIL(!fgets(tc_version, sizeof(tc_version), tc)))
+               return false;
+       if (strstr(tc_version, ", libbpf "))
+               prog = "test_sk_assign_libbpf.bpf.o";
+       else
+               prog = "test_sk_assign.bpf.o";
+       if (CHECK_FAIL(pclose(tc)))
+               return false;
 
        /* Move to a new networking namespace */
        if (CHECK_FAIL(unshare(CLONE_NEWNET)))
@@ -46,8 +62,8 @@ configure_stack(void)
        /* Load qdisc, BPF program */
        if (CHECK_FAIL(system("tc qdisc add dev lo clsact")))
                return false;
-       sprintf(tc_cmd, "%s %s %s %s", "tc filter add dev lo ingress bpf",
-                      "direct-action object-file ./test_sk_assign.bpf.o",
+       sprintf(tc_cmd, "%s %s %s %s %s", "tc filter add dev lo ingress bpf",
+                      "direct-action object-file", prog,
                       "section tc",
                       (env.verbosity < VERBOSE_VERY) ? " 2>/dev/null" : "verbose");
        if (CHECK(system(tc_cmd), "BPF load failed;",
@@ -129,15 +145,12 @@ get_port(int fd)
 static ssize_t
 rcv_msg(int srv_client, int type)
 {
-       struct sockaddr_storage ss;
        char buf[BUFSIZ];
-       socklen_t slen;
 
        if (type == SOCK_STREAM)
                return read(srv_client, &buf, sizeof(buf));
        else
-               return recvfrom(srv_client, &buf, sizeof(buf), 0,
-                               (struct sockaddr *)&ss, &slen);
+               return recvfrom(srv_client, &buf, sizeof(buf), 0, NULL, NULL);
 }
 
 static int
index 98c6493..21b19b7 100644 (file)
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_endian.h>
 
+#if defined(IPROUTE2_HAVE_LIBBPF)
+/* Use a new-style map definition. */
+struct {
+       __uint(type, BPF_MAP_TYPE_SOCKMAP);
+       __type(key, int);
+       __type(value, __u64);
+       __uint(pinning, LIBBPF_PIN_BY_NAME);
+       __uint(max_entries, 1);
+} server_map SEC(".maps");
+#else
 /* Pin map under /sys/fs/bpf/tc/globals/<map name> */
 #define PIN_GLOBAL_NS 2
 
@@ -35,6 +45,7 @@ struct {
        .max_elem = 1,
        .pinning = PIN_GLOBAL_NS,
 };
+#endif
 
 char _license[] SEC("license") = "GPL";
 
diff --git a/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c b/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c
new file mode 100644 (file)
index 0000000..dcf46ad
--- /dev/null
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+#define IPROUTE2_HAVE_LIBBPF
+#include "test_sk_assign.c"