af_xdp: fix xdp socket create fail 74/37274/6
authorChen Yahui <goodluckwillcomesoon@gmail.com>
Wed, 28 Sep 2022 13:30:07 +0000 (21:30 +0800)
committerBeno�t Ganne <bganne@cisco.com>
Tue, 24 Jan 2023 08:53:26 +0000 (08:53 +0000)
In libbpf code, xsk_socket__create will call xsk_link_lookup to get the
xdp_sock bpf prog. But xsk_link_lookup can't get any bpf prog. This will
cause Libbpf not to insert the fd into xsks_map and return ERROR.

The solution to this problem is to insert fd into xsks_map ourselves
instead of libbpf.

Type: fix
Change-Id: Ic5d279c6ddc02d67371262d6106a5b53b70e7913
Signed-off-by: Chen Yahui <goodluckwillcomesoon@gmail.com>
src/plugins/af_xdp/device.c

index 385a6e5..a269e3c 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/if_link.h>
 #include <linux/sockios.h>
 #include <linux/limits.h>
-#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
 #include <vlib/vlib.h>
 #include <vlib/unix/unix.h>
 #include <vlib/pci/pci.h>
@@ -326,6 +326,8 @@ af_xdp_create_queue (vlib_main_t *vm, af_xdp_create_if_args_t *args,
       sock_config.bind_flags |= XDP_ZEROCOPY;
       break;
     }
+  if (args->prog)
+    sock_config.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
   if (xsk_socket__create
       (xsk, ad->linux_ifname, qid, *umem, rx, tx, &sock_config))
     {
@@ -338,13 +340,27 @@ af_xdp_create_queue (vlib_main_t *vm, af_xdp_create_if_args_t *args,
     }
 
   fd = xsk_socket__fd (*xsk);
+  if (args->prog)
+    {
+      struct bpf_map *map =
+       bpf_object__find_map_by_name (ad->bpf_obj, "xsks_map");
+      int ret = xsk_socket__update_xskmap (*xsk, bpf_map__fd (map));
+      if (ret)
+       {
+         args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
+         args->error = clib_error_return_unix (
+           0, "xsk_socket__update_xskmap %s qid %d return %d",
+           ad->linux_ifname, qid, ret);
+         goto err2;
+       }
+    }
   optlen = sizeof (opt);
 #ifndef SOL_XDP
 #define SOL_XDP 283
 #endif
   if (getsockopt (fd, SOL_XDP, XDP_OPTIONS, &opt, &optlen))
     {
-      args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
+      args->rv = VNET_API_ERROR_SYSCALL_ERROR_4;
       args->error =
        clib_error_return_unix (0, "getsockopt(XDP_OPTIONS) failed");
       goto err2;