selftests: net: move xdp_helper to net/lib
authorBui Quang Minh <minhquangbui99@gmail.com>
Fri, 25 Apr 2025 07:10:15 +0000 (14:10 +0700)
committerJakub Kicinski <kuba@kernel.org>
Mon, 28 Apr 2025 22:49:10 +0000 (15:49 -0700)
Move xdp_helper to net/lib to make it easier for other selftests to use
the helper.

Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20250425071018.36078-2-minhquangbui99@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/testing/selftests/drivers/net/.gitignore
tools/testing/selftests/drivers/net/Makefile
tools/testing/selftests/drivers/net/ksft.h [deleted file]
tools/testing/selftests/drivers/net/napi_id_helper.c
tools/testing/selftests/drivers/net/queues.py
tools/testing/selftests/drivers/net/xdp_helper.c [deleted file]
tools/testing/selftests/net/lib/.gitignore
tools/testing/selftests/net/lib/Makefile
tools/testing/selftests/net/lib/ksft.h [new file with mode: 0644]
tools/testing/selftests/net/lib/xdp_helper.c [new file with mode: 0644]

index 72d2124fd5138520dec8c44a9453c704f0d1d5ff..d634d8395d90c2ee1a8bc47a954c45c5f54f90c3 100644 (file)
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
 napi_id_helper
-xdp_helper
index 47247c2ef948bcd3f4c9b0ba9200e1c8217b73a7..17db31aa58c94280c764b6782e7bbcdaad4f727f 100644 (file)
@@ -8,7 +8,6 @@ TEST_INCLUDES := $(wildcard lib/py/*.py) \
 
 TEST_GEN_FILES := \
        napi_id_helper \
-       xdp_helper \
 # end of TEST_GEN_FILES
 
 TEST_PROGS := \
diff --git a/tools/testing/selftests/drivers/net/ksft.h b/tools/testing/selftests/drivers/net/ksft.h
deleted file mode 100644 (file)
index 17dc34a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#if !defined(__NET_KSFT_H__)
-#define __NET_KSFT_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static inline void ksft_ready(void)
-{
-       const char msg[7] = "ready\n";
-       char *env_str;
-       int fd;
-
-       env_str = getenv("KSFT_READY_FD");
-       if (env_str) {
-               fd = atoi(env_str);
-               if (!fd) {
-                       fprintf(stderr, "invalid KSFT_READY_FD = '%s'\n",
-                               env_str);
-                       return;
-               }
-       } else {
-               fd = STDOUT_FILENO;
-       }
-
-       write(fd, msg, sizeof(msg));
-       if (fd != STDOUT_FILENO)
-               close(fd);
-}
-
-static inline void ksft_wait(void)
-{
-       char *env_str;
-       char byte;
-       int fd;
-
-       env_str = getenv("KSFT_WAIT_FD");
-       if (env_str) {
-               fd = atoi(env_str);
-               if (!fd) {
-                       fprintf(stderr, "invalid KSFT_WAIT_FD = '%s'\n",
-                               env_str);
-                       return;
-               }
-       } else {
-               /* Not running in KSFT env, wait for input from STDIN instead */
-               fd = STDIN_FILENO;
-       }
-
-       read(fd, &byte, sizeof(byte));
-       if (fd != STDIN_FILENO)
-               close(fd);
-}
-
-#endif
index 7e8e7d373b612943f030e2cc2aa1798acf1843fb..eecd610c21095049e184a25be7dfa887df66da51 100644 (file)
@@ -8,7 +8,7 @@
 #include <arpa/inet.h>
 #include <sys/socket.h>
 
-#include "ksft.h"
+#include "../../net/lib/ksft.h"
 
 int main(int argc, char *argv[])
 {
index 06abd3f233e1ff3ef30836b7865a8d73b793eb3a..236005290a33eaf58eade63d779725e1b0a74918 100755 (executable)
@@ -26,13 +26,13 @@ def nl_get_queues(cfg, nl, qtype='rx'):
 
 def check_xsk(cfg, nl, xdp_queue_id=0) -> None:
     # Probe for support
-    xdp = cmd(f'{cfg.test_dir / "xdp_helper"} - -', fail=False)
+    xdp = cmd(f'{cfg.net_lib_dir / "xdp_helper"} - -', fail=False)
     if xdp.ret == 255:
         raise KsftSkipEx('AF_XDP unsupported')
     elif xdp.ret > 0:
         raise KsftFailEx('unable to create AF_XDP socket')
 
-    with bkg(f'{cfg.test_dir / "xdp_helper"} {cfg.ifindex} {xdp_queue_id}',
+    with bkg(f'{cfg.net_lib_dir / "xdp_helper"} {cfg.ifindex} {xdp_queue_id}',
              ksft_wait=3):
 
         rx = tx = False
diff --git a/tools/testing/selftests/drivers/net/xdp_helper.c b/tools/testing/selftests/drivers/net/xdp_helper.c
deleted file mode 100644 (file)
index d5bb8ac..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <linux/if_xdp.h>
-#include <linux/if_link.h>
-#include <net/if.h>
-#include <inttypes.h>
-
-#include "ksft.h"
-
-#define UMEM_SZ (1U << 16)
-#define NUM_DESC (UMEM_SZ / 2048)
-
-
-/* this is a simple helper program that creates an XDP socket and does the
- * minimum necessary to get bind() to succeed.
- *
- * this test program is not intended to actually process packets, but could be
- * extended in the future if that is actually needed.
- *
- * it is used by queues.py to ensure the xsk netlinux attribute is set
- * correctly.
- */
-int main(int argc, char **argv)
-{
-       struct xdp_umem_reg umem_reg = { 0 };
-       struct sockaddr_xdp sxdp = { 0 };
-       int num_desc = NUM_DESC;
-       void *umem_area;
-       int ifindex;
-       int sock_fd;
-       int queue;
-
-       if (argc != 3) {
-               fprintf(stderr, "Usage: %s ifindex queue_id\n", argv[0]);
-               return 1;
-       }
-
-       sock_fd = socket(AF_XDP, SOCK_RAW, 0);
-       if (sock_fd < 0) {
-               perror("socket creation failed");
-               /* if the kernel doesn't support AF_XDP, let the test program
-                * know with -1. All other error paths return 1.
-                */
-               if (errno == EAFNOSUPPORT)
-                       return -1;
-               return 1;
-       }
-
-       /* "Probing mode", just checking if AF_XDP sockets are supported */
-       if (!strcmp(argv[1], "-") && !strcmp(argv[2], "-")) {
-               printf("AF_XDP support detected\n");
-               close(sock_fd);
-               return 0;
-       }
-
-       ifindex = atoi(argv[1]);
-       queue = atoi(argv[2]);
-
-       umem_area = mmap(NULL, UMEM_SZ, PROT_READ | PROT_WRITE, MAP_PRIVATE |
-                       MAP_ANONYMOUS, -1, 0);
-       if (umem_area == MAP_FAILED) {
-               perror("mmap failed");
-               return 1;
-       }
-
-       umem_reg.addr = (uintptr_t)umem_area;
-       umem_reg.len = UMEM_SZ;
-       umem_reg.chunk_size = 2048;
-       umem_reg.headroom = 0;
-
-       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_REG, &umem_reg,
-                  sizeof(umem_reg));
-       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_FILL_RING, &num_desc,
-                  sizeof(num_desc));
-       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, &num_desc,
-                  sizeof(num_desc));
-       setsockopt(sock_fd, SOL_XDP, XDP_RX_RING, &num_desc, sizeof(num_desc));
-
-       sxdp.sxdp_family = AF_XDP;
-       sxdp.sxdp_ifindex = ifindex;
-       sxdp.sxdp_queue_id = queue;
-       sxdp.sxdp_flags = 0;
-
-       if (bind(sock_fd, (struct sockaddr *)&sxdp, sizeof(sxdp)) != 0) {
-               munmap(umem_area, UMEM_SZ);
-               perror("bind failed");
-               close(sock_fd);
-               return 1;
-       }
-
-       ksft_ready();
-       ksft_wait();
-
-       /* parent program will write a byte to stdin when its ready for this
-        * helper to exit
-        */
-
-       close(sock_fd);
-       return 0;
-}
index 1ebc6187f421c0d6dae6658096acc8f1757b2bc0..bbc97d6bf55643211123426c8239bc33ec12588d 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 csum
+xdp_helper
index c22623b9a2a5f5a4160081f2c100cbc4bc71b27f..88c4bc4614599836fed53dc42b59c7d14cf29d75 100644 (file)
@@ -10,6 +10,7 @@ TEST_FILES += ../../../../net/ynl
 
 TEST_GEN_FILES += csum
 TEST_GEN_FILES += $(patsubst %.c,%.o,$(wildcard *.bpf.c))
+TEST_GEN_FILES += xdp_helper
 
 TEST_INCLUDES := $(wildcard py/*.py sh/*.sh)
 
diff --git a/tools/testing/selftests/net/lib/ksft.h b/tools/testing/selftests/net/lib/ksft.h
new file mode 100644 (file)
index 0000000..17dc34a
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(__NET_KSFT_H__)
+#define __NET_KSFT_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static inline void ksft_ready(void)
+{
+       const char msg[7] = "ready\n";
+       char *env_str;
+       int fd;
+
+       env_str = getenv("KSFT_READY_FD");
+       if (env_str) {
+               fd = atoi(env_str);
+               if (!fd) {
+                       fprintf(stderr, "invalid KSFT_READY_FD = '%s'\n",
+                               env_str);
+                       return;
+               }
+       } else {
+               fd = STDOUT_FILENO;
+       }
+
+       write(fd, msg, sizeof(msg));
+       if (fd != STDOUT_FILENO)
+               close(fd);
+}
+
+static inline void ksft_wait(void)
+{
+       char *env_str;
+       char byte;
+       int fd;
+
+       env_str = getenv("KSFT_WAIT_FD");
+       if (env_str) {
+               fd = atoi(env_str);
+               if (!fd) {
+                       fprintf(stderr, "invalid KSFT_WAIT_FD = '%s'\n",
+                               env_str);
+                       return;
+               }
+       } else {
+               /* Not running in KSFT env, wait for input from STDIN instead */
+               fd = STDIN_FILENO;
+       }
+
+       read(fd, &byte, sizeof(byte));
+       if (fd != STDIN_FILENO)
+               close(fd);
+}
+
+#endif
diff --git a/tools/testing/selftests/net/lib/xdp_helper.c b/tools/testing/selftests/net/lib/xdp_helper.c
new file mode 100644 (file)
index 0000000..d5bb8ac
--- /dev/null
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <linux/if_xdp.h>
+#include <linux/if_link.h>
+#include <net/if.h>
+#include <inttypes.h>
+
+#include "ksft.h"
+
+#define UMEM_SZ (1U << 16)
+#define NUM_DESC (UMEM_SZ / 2048)
+
+
+/* this is a simple helper program that creates an XDP socket and does the
+ * minimum necessary to get bind() to succeed.
+ *
+ * this test program is not intended to actually process packets, but could be
+ * extended in the future if that is actually needed.
+ *
+ * it is used by queues.py to ensure the xsk netlinux attribute is set
+ * correctly.
+ */
+int main(int argc, char **argv)
+{
+       struct xdp_umem_reg umem_reg = { 0 };
+       struct sockaddr_xdp sxdp = { 0 };
+       int num_desc = NUM_DESC;
+       void *umem_area;
+       int ifindex;
+       int sock_fd;
+       int queue;
+
+       if (argc != 3) {
+               fprintf(stderr, "Usage: %s ifindex queue_id\n", argv[0]);
+               return 1;
+       }
+
+       sock_fd = socket(AF_XDP, SOCK_RAW, 0);
+       if (sock_fd < 0) {
+               perror("socket creation failed");
+               /* if the kernel doesn't support AF_XDP, let the test program
+                * know with -1. All other error paths return 1.
+                */
+               if (errno == EAFNOSUPPORT)
+                       return -1;
+               return 1;
+       }
+
+       /* "Probing mode", just checking if AF_XDP sockets are supported */
+       if (!strcmp(argv[1], "-") && !strcmp(argv[2], "-")) {
+               printf("AF_XDP support detected\n");
+               close(sock_fd);
+               return 0;
+       }
+
+       ifindex = atoi(argv[1]);
+       queue = atoi(argv[2]);
+
+       umem_area = mmap(NULL, UMEM_SZ, PROT_READ | PROT_WRITE, MAP_PRIVATE |
+                       MAP_ANONYMOUS, -1, 0);
+       if (umem_area == MAP_FAILED) {
+               perror("mmap failed");
+               return 1;
+       }
+
+       umem_reg.addr = (uintptr_t)umem_area;
+       umem_reg.len = UMEM_SZ;
+       umem_reg.chunk_size = 2048;
+       umem_reg.headroom = 0;
+
+       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_REG, &umem_reg,
+                  sizeof(umem_reg));
+       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_FILL_RING, &num_desc,
+                  sizeof(num_desc));
+       setsockopt(sock_fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, &num_desc,
+                  sizeof(num_desc));
+       setsockopt(sock_fd, SOL_XDP, XDP_RX_RING, &num_desc, sizeof(num_desc));
+
+       sxdp.sxdp_family = AF_XDP;
+       sxdp.sxdp_ifindex = ifindex;
+       sxdp.sxdp_queue_id = queue;
+       sxdp.sxdp_flags = 0;
+
+       if (bind(sock_fd, (struct sockaddr *)&sxdp, sizeof(sxdp)) != 0) {
+               munmap(umem_area, UMEM_SZ);
+               perror("bind failed");
+               close(sock_fd);
+               return 1;
+       }
+
+       ksft_ready();
+       ksft_wait();
+
+       /* parent program will write a byte to stdin when its ready for this
+        * helper to exit
+        */
+
+       close(sock_fd);
+       return 0;
+}