netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/3] Qemu: virtio-net XDP offload
@ 2019-11-26 10:09 Prashant Bhole
  2019-11-26 10:09 ` [RFC 1/3] configure: add libbpf support Prashant Bhole
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Prashant Bhole @ 2019-11-26 10:09 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang, qemu-devel
  Cc: Prashant Bhole, David S . Miller, Alexei Starovoitov,
	Daniel Borkmann, Jakub Kicinski, Jesper Dangaard Brouer,
	John Fastabend, Martin KaFai Lau, Song Liu, Yonghong Song,
	Andrii Nakryiko, netdev, kvm

Note: This RFC has been sent to netdev as well as qemu-devel lists

This patchset implements XDP offload feature in qemu. The successful
operation of this feature depends on availability of XDP offload
feature in guest, qemu and host. When this feature isn't available in
qemu or host, the request from guest to offload an XDP program should
fail.

Patch 1/3 adds support for libbpf in configure script.
Patch 2/2 enables offloading of ebpf program.
Patch 3/3 enabled offloading of ebpf map.

Points for improvement (TODO):
- In future virtio can have feature bit for offloading capability

- TUNGETFEATURES should have a flag to notify about offloading
  capability

- Submit virtio spec patch to describe XDP offloading feature

- DoS: Offloaded map uses host's memory which is other than what has
  been allocated for the guest. Offloading many maps of large size can
  be one of the DoS strategy. Hence qemu should have parameter to
  limit how many maps guest can offload or how much memory offloaded
  maps use.

Note:
This set directly modifies virtio_net.h header instead of
importing it from existing kernel headers because relevant changes
aren't present in kernel repository yet. Hence changes to virtio_net.h
are for RFC purpose only.


Jason Wang (2):
  virtio-net: add support for offloading XDP program
  virtio-net: add support for offloading an ebpf map

Prashant Bhole (1):
  configure: add libbpf support

 configure                                   |  23 +++
 hw/net/Makefile.objs                        |   2 +
 hw/net/virtio-net.c                         | 157 ++++++++++++++++++++
 include/net/tap.h                           |   2 +
 include/standard-headers/linux/virtio_net.h |  50 +++++++
 net/Makefile.objs                           |   1 +
 net/tap-bsd.c                               |   5 +
 net/tap-linux.c                             |  48 ++++++
 net/tap-linux.h                             |   1 +
 net/tap-solaris.c                           |   5 +
 net/tap-stub.c                              |   5 +
 net/tap.c                                   |   7 +
 net/tap_int.h                               |   1 +
 13 files changed, 307 insertions(+)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC 1/3] configure: add libbpf support
  2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
@ 2019-11-26 10:09 ` Prashant Bhole
  2019-11-26 10:09 ` [RFC 2/3] virtio-net: add support for offloading XDP program Prashant Bhole
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Prashant Bhole @ 2019-11-26 10:09 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang, qemu-devel
  Cc: Prashant Bhole, David S . Miller, Alexei Starovoitov,
	Daniel Borkmann, Jakub Kicinski, Jesper Dangaard Brouer,
	John Fastabend, Martin KaFai Lau, Song Liu, Yonghong Song,
	Andrii Nakryiko, netdev, kvm

This is a preparation to add libbpf support for Qemu. When it is
enabled Qemu can load eBPF programs and manipulated eBPF maps
libbpf APIs.

When configured with --enable-libbpf, availability of libbpf is
checked. If it exists then CONFIG_LIBBPF is defined and the qemu
binary is linked with libbpf.

Signed-off-by: Prashant Bhole <prashantbhole.linux@gmail.com>
---
 configure | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/configure b/configure
index 6099be1d84..a7e8a8450d 100755
--- a/configure
+++ b/configure
@@ -504,6 +504,7 @@ debug_mutex="no"
 libpmem=""
 default_devices="yes"
 plugins="no"
+libbpf="no"
 
 supported_cpu="no"
 supported_os="no"
@@ -1539,6 +1540,8 @@ for opt do
   ;;
   --disable-plugins) plugins="no"
   ;;
+  --enable-libbpf) libbpf="yes"
+  ;;
   *)
       echo "ERROR: unknown option $opt"
       echo "Try '$0 --help' for more information"
@@ -1825,6 +1828,7 @@ disabled with --disable-FEATURE, default is enabled if available:
   debug-mutex     mutex debugging support
   libpmem         libpmem support
   xkbcommon       xkbcommon support
+  libbpf      eBPF program support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -6084,6 +6088,19 @@ case "$slirp" in
     ;;
 esac
 
+##########################################
+# Do we have libbpf
+if test "$libbpf" != "no" ; then
+  if $pkg_config libbpf; then
+    libbpf="yes"
+    libbpf_libs=$($pkg_config --libs libbpf)
+  else
+    if test "$libbpf" == "yes" ; then
+      feature_not_found "libbpf" "Install libbpf devel"
+    fi
+    libbpf="no"
+  fi
+fi
 
 ##########################################
 # End of CC checks
@@ -6599,6 +6616,7 @@ echo "libpmem support   $libpmem"
 echo "libudev           $libudev"
 echo "default devices   $default_devices"
 echo "plugin support    $plugins"
+echo "XDP offload support $libbpf"
 
 if test "$supported_cpu" = "no"; then
     echo
@@ -7457,6 +7475,11 @@ if test "$plugins" = "yes" ; then
     fi
 fi
 
+if test "$libbpf" = "yes" ; then
+  echo "CONFIG_LIBBPF=y" >> $config_host_mak
+  echo "LIBBPF_LIBS=$libbpf_libs" >> $config_host_mak
+fi
+
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
 elif test "$ARCH" = "sparc64" ; then
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC 2/3] virtio-net: add support for offloading XDP program
  2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
  2019-11-26 10:09 ` [RFC 1/3] configure: add libbpf support Prashant Bhole
@ 2019-11-26 10:09 ` Prashant Bhole
  2019-11-26 10:09 ` [RFC 3/3] virtio-net: add support for offloading an ebpf map Prashant Bhole
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Prashant Bhole @ 2019-11-26 10:09 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang, qemu-devel
  Cc: David S . Miller, Alexei Starovoitov, Daniel Borkmann,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko,
	netdev, kvm, Prashant Bhole

From: Jason Wang <jasowang@redhat.com>

This feature involves offloading of XDP program and ebpf map from
the guest to the host. This patch takes care of offloadin of program.

A handler for VIRTIO_NET_CTRL_EBPF command is added in virtio-net.
The control buffer consist of struct virtio_net_ctrl_ebpf_prog and
followed by an ebpf program instructions. An array of bpf_insn is
prepared and passed to libbpf API bpf_load_program. The program fd is
retuned by the API is then attached to tap fd using TUNSETOFFLOADEDXDP
ioctl command.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Co-developed-by: Prashant Bhole <prashantbhole.linux@gmail.com>
Signed-off-by: Prashant Bhole <prashantbhole.linux@gmail.com>
---
 hw/net/virtio-net.c                         | 69 +++++++++++++++++++++
 include/net/tap.h                           |  2 +
 include/standard-headers/linux/virtio_net.h | 27 ++++++++
 net/Makefile.objs                           |  1 +
 net/tap-bsd.c                               |  5 ++
 net/tap-linux.c                             | 48 ++++++++++++++
 net/tap-linux.h                             |  1 +
 net/tap-solaris.c                           |  5 ++
 net/tap-stub.c                              |  5 ++
 net/tap.c                                   |  7 +++
 net/tap_int.h                               |  1 +
 11 files changed, 171 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 97a5113f7e..7cc1bd1654 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -43,6 +43,11 @@
 #include "monitor/qdev.h"
 #include "hw/pci/pci.h"
 
+#ifdef CONFIG_LIBBPF
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+#endif
+
 #define VIRTIO_NET_VM_VERSION    11
 
 #define MAC_TABLE_ENTRIES    64
@@ -628,6 +633,21 @@ static int peer_attach(VirtIONet *n, int index)
     return tap_enable(nc->peer);
 }
 
+static int peer_attach_ebpf(VirtIONet *n, int len, void *insns, uint8_t gpl)
+{
+    NetClientState *nc = qemu_get_subqueue(n->nic, 0);
+
+    if (!nc->peer) {
+        return 0;
+    }
+
+    if (nc->peer->info->type != NET_CLIENT_DRIVER_TAP) {
+        return 0;
+    }
+
+    return tap_attach_ebpf(nc->peer, len, insns, gpl);
+}
+
 static int peer_detach(VirtIONet *n, int index)
 {
     NetClientState *nc = qemu_get_subqueue(n->nic, index);
@@ -991,6 +1011,53 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
     }
 }
 
+static int virtio_net_handle_ebpf_prog(VirtIONet *n, struct iovec *iov,
+                                       unsigned int iov_cnt)
+{
+#ifdef CONFIG_LIBBPF
+    struct bpf_insn prog[4096];
+    struct virtio_net_ctrl_ebpf_prog ctrl;
+    size_t s;
+    int err = VIRTIO_NET_ERR;
+
+    s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
+    if (s != sizeof(ctrl)) {
+        error_report("Invalid ebpf prog control buffer");
+        goto err;
+    }
+
+    if (ctrl.cmd == VIRTIO_NET_BPF_CMD_SET_OFFLOAD) {
+        s = iov_to_buf(iov, iov_cnt, sizeof(ctrl), prog, sizeof(prog));
+        if (s != ctrl.len) {
+            error_report("Invalid ebpf prog control buffer");
+            goto err;
+        }
+
+        err = peer_attach_ebpf(n, s, prog, ctrl.gpl_compatible);
+            if (err) {
+                error_report("Failed to attach XDP program");
+                goto err;
+            }
+    } else if (ctrl.cmd == VIRTIO_NET_BPF_CMD_UNSET_OFFLOAD) {
+        err = peer_attach_ebpf(n, 0, NULL, 0);
+    }
+err:
+    return err ? VIRTIO_NET_ERR : VIRTIO_NET_OK;
+#else
+    return VIRTIO_NET_ERR;
+#endif
+}
+
+static int virtio_net_handle_ebpf(VirtIONet *n, uint8_t cmd,
+                                  struct iovec *iov, unsigned int iov_cnt)
+{
+    if (cmd == VIRTIO_NET_CTRL_EBPF_PROG) {
+        return virtio_net_handle_ebpf_prog(n, iov, iov_cnt);
+    }
+
+    return VIRTIO_NET_ERR;
+}
+
 static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
                                  struct iovec *iov, unsigned int iov_cnt)
 {
@@ -1208,6 +1275,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
             status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
         } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
             status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
+        } else if (ctrl.class == VIRTIO_NET_CTRL_EBPF) {
+            status = virtio_net_handle_ebpf(n, ctrl.cmd, iov, iov_cnt);
         }
 
         s = iov_from_buf(elem->in_sg, elem->in_num, 0, &status, sizeof(status));
diff --git a/include/net/tap.h b/include/net/tap.h
index 5d585515f9..19c507a1c2 100644
--- a/include/net/tap.h
+++ b/include/net/tap.h
@@ -33,6 +33,8 @@ int tap_disable(NetClientState *nc);
 
 int tap_get_fd(NetClientState *nc);
 
+int tap_attach_ebpf(NetClientState *nc, int len, void *insns, uint8_t gpl);
+
 struct vhost_net;
 struct vhost_net *tap_get_vhost_net(NetClientState *nc);
 
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
index 260c3681d7..83292c81bc 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -261,4 +261,31 @@ struct virtio_net_ctrl_mq {
 #define VIRTIO_NET_CTRL_GUEST_OFFLOADS   5
 #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
 
+/*
+ * Control XDP offloads offloads
+ *
+ * When guest wants to offload XDP program to tap device, it calls
+ * VIRTIO_NET_CTRL_EBPF_PROG along with VIRTIO_NET_BPF_CMD_SET_OFFLOAD
+ * subcommands. When offloading is successful, the tap device run offloaded
+ * XDP program for each packet before sending it to the guest.
+ *
+ * VIRTIO_NET_BPF_CMD_UNSET_OFFLOAD removes the the offloaded program from
+ * the tap device, if exists.
+ */
+
+struct virtio_net_ctrl_ebpf_prog {
+	/* program length in bytes */
+	__virtio32 len;
+	__virtio16 cmd;
+	__virtio16 gpl_compatible;
+	uint8_t insns[0];
+};
+
+#define VIRTIO_NET_CTRL_EBPF 	6
+ #define VIRTIO_NET_CTRL_EBPF_PROG 1
+
+/* Commands for VIRTIO_NET_CTRL_EBPF_PROG */
+#define VIRTIO_NET_BPF_CMD_SET_OFFLOAD 1
+#define VIRTIO_NET_BPF_CMD_UNSET_OFFLOAD 2
+
 #endif /* _LINUX_VIRTIO_NET_H */
diff --git a/net/Makefile.objs b/net/Makefile.objs
index c5d076d19c..e7645225be 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -28,5 +28,6 @@ common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
 common-obj-$(CONFIG_WIN32) += tap-win32.o
 
 vde.o-libs = $(VDE_LIBS)
+tap-linux.o-libs = $(LIBBPF_LIBS)
 
 common-obj-$(CONFIG_CAN_BUS) += can/
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index a5c3707f80..e4e2a5c799 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -259,3 +259,8 @@ int tap_fd_get_ifname(int fd, char *ifname)
 {
     return -1;
 }
+
+int tap_fd_attach_ebpf(int fd, int len, void *insns, uint8_t gpl)
+{
+    return -EINVAL;
+}
diff --git a/net/tap-linux.c b/net/tap-linux.c
index e0dd442ee3..3ff806bf4f 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -31,6 +31,8 @@
 
 #include <net/if.h>
 #include <sys/ioctl.h>
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
 
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -314,3 +316,49 @@ int tap_fd_get_ifname(int fd, char *ifname)
     pstrcpy(ifname, sizeof(ifr.ifr_name), ifr.ifr_name);
     return 0;
 }
+
+int tap_fd_attach_ebpf(int fd, int len, void *insns, uint8_t gpl)
+{
+#ifdef CONFIG_LIBBPF
+    struct bpf_insn *prog = (struct bpf_insn *)insns;
+    static char log_buf[65536];
+    char license[16] = {0};
+    int num_insn;
+    int bpf_fd;
+    int ret;
+
+    if (!prog) {
+        bpf_fd = -1;
+        ret = ioctl(fd, TUNSETOFFLOADEDXDP, &bpf_fd);
+        if (ret) {
+            error_report("Failed to remove offloaded XDP: %s", strerror(errno));
+            return -EFAULT;
+        }
+        return ret;
+    }
+
+    num_insn = len / sizeof(prog[0]);
+    if (gpl) {
+        strncpy(license, "GPL", sizeof(license));
+    }
+
+    bpf_fd = bpf_load_program(BPF_PROG_TYPE_XDP, prog, num_insn, license,
+                              0, log_buf, sizeof(log_buf));
+    if (bpf_fd < 0) {
+        error_report("Failed to load XDP program: %s", strerror(errno));
+        error_report("ebpf verifier log: %s", log_buf);
+        return -EFAULT;
+    }
+
+    ret = ioctl(fd, TUNSETOFFLOADEDXDP, &bpf_fd);
+    if (ret) {
+        error_report("Failed to set offloaded XDP: %s", strerror(errno));
+        return -EFAULT;
+    }
+    close(bpf_fd);
+
+    return ret;
+#else
+    return -EINVAL;
+#endif
+}
diff --git a/net/tap-linux.h b/net/tap-linux.h
index 2f36d100fc..791aeaebc4 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -31,6 +31,7 @@
 #define TUNSETQUEUE  _IOW('T', 217, int)
 #define TUNSETVNETLE _IOW('T', 220, int)
 #define TUNSETVNETBE _IOW('T', 222, int)
+#define TUNSETOFFLOADEDXDP _IOW('T', 228, int)
 
 #endif
 
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 4725d2314e..38b9136b5f 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -254,3 +254,8 @@ int tap_fd_get_ifname(int fd, char *ifname)
 {
     return -1;
 }
+
+int tap_fd_attach_ebpf(int fd, int len, void *insns, uint8_t gpl)
+{
+    return -EINVAL;
+}
diff --git a/net/tap-stub.c b/net/tap-stub.c
index a9ab8f8293..5f4161b390 100644
--- a/net/tap-stub.c
+++ b/net/tap-stub.c
@@ -85,3 +85,8 @@ int tap_fd_get_ifname(int fd, char *ifname)
 {
     return -1;
 }
+
+int tap_fd_attach_ebpf(int fd, int len, void *insns, uint8_t gpl)
+{
+    return -EINVAL;
+}
diff --git a/net/tap.c b/net/tap.c
index 6207f61f84..3dba8eacb1 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -971,6 +971,13 @@ int tap_enable(NetClientState *nc)
     }
 }
 
+int tap_attach_ebpf(NetClientState *nc, int len, void *insns, uint8_t gpl)
+{
+    TAPState *s = DO_UPCAST(TAPState, nc, nc);
+
+    return tap_fd_attach_ebpf(s->fd, len, insns, gpl);
+}
+
 int tap_disable(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
diff --git a/net/tap_int.h b/net/tap_int.h
index e3194b23f4..af641607e2 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -44,5 +44,6 @@ int tap_fd_set_vnet_be(int fd, int vnet_is_be);
 int tap_fd_enable(int fd);
 int tap_fd_disable(int fd);
 int tap_fd_get_ifname(int fd, char *ifname);
+int tap_fd_attach_ebpf(int fd, int len, void *insns, uint8_t gpl);
 
 #endif /* NET_TAP_INT_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC 3/3] virtio-net: add support for offloading an ebpf map
  2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
  2019-11-26 10:09 ` [RFC 1/3] configure: add libbpf support Prashant Bhole
  2019-11-26 10:09 ` [RFC 2/3] virtio-net: add support for offloading XDP program Prashant Bhole
@ 2019-11-26 10:09 ` Prashant Bhole
  2019-11-26 10:33 ` [RFC 0/3] Qemu: virtio-net XDP offload no-reply
  2019-11-26 10:36 ` no-reply
  4 siblings, 0 replies; 7+ messages in thread
From: Prashant Bhole @ 2019-11-26 10:09 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang, qemu-devel
  Cc: David S . Miller, Alexei Starovoitov, Daniel Borkmann,
	Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
	Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko,
	netdev, kvm, Prashant Bhole

From: Jason Wang <jasowang@redhat.com>

This change is a part of XDP offload feature. It handles offloading
of eBPF map from the guest.

A command handler for VIRTIO_NET_CTRL_EBPF now checks for subcommand
VIRTIO_NET_CTRL_EBPF_MAP and. The control buffer consists of struct
virtio_net_ctrl_ebpf_map followed by map key/value or key/key pair.
Map manipulation is done using libbpf APIs.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Co-developed-by: Prashant Bhole <prashantbhole.linux@gmail.com>
Signed-off-by: Prashant Bhole <prashantbhole.linux@gmail.com>
---
 hw/net/Makefile.objs                        |  2 +
 hw/net/virtio-net.c                         | 88 +++++++++++++++++++++
 include/standard-headers/linux/virtio_net.h | 23 ++++++
 3 files changed, 113 insertions(+)

diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 7907d2c199..5928497a01 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -52,3 +52,5 @@ common-obj-$(CONFIG_ROCKER) += rocker/rocker.o rocker/rocker_fp.o \
 obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o
 
 common-obj-$(CONFIG_CAN_BUS) += can/
+
+virtio-net.o-libs := $(LIBBPF_LIBS)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7cc1bd1654..3c49273796 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1011,6 +1011,92 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
     }
 }
 
+static int virtio_net_handle_ebpf_map(VirtIONet *n, struct iovec *iov,
+                                      unsigned int iov_cnt)
+{
+#ifdef CONFIG_LIBBPF
+    struct virtio_net_ctrl_ebpf_map *ctrl = NULL;
+    struct bpf_create_map_attr map_attr = {};
+    uint8_t *key, *val;
+    uint32_t buf_len;
+    int fd, err = 0;
+    size_t s;
+
+    s = iov_to_buf(iov, iov_cnt, 0, &buf_len, sizeof(buf_len));
+    if (s != sizeof(buf_len)) {
+        goto err;
+    }
+
+    ctrl = malloc(sizeof(*ctrl) + buf_len);
+    if (!ctrl) {
+        goto err;
+    }
+
+    s = iov_to_buf(iov, iov_cnt, 0, ctrl, sizeof(*ctrl) + buf_len);
+    if (s != (sizeof(*ctrl) + buf_len)) {
+        error_report("Invalid map control buffer");
+        goto err;
+    }
+
+    key = ctrl->buf;
+    val = ctrl->buf + ctrl->key_size;
+
+    switch (ctrl->cmd) {
+    case VIRTIO_NET_BPF_CMD_CREATE_MAP:
+        map_attr.map_type = ctrl->map_type;
+        map_attr.map_flags = ctrl->map_flags;
+        map_attr.key_size = ctrl->key_size;
+        map_attr.value_size = ctrl->value_size;
+        map_attr.max_entries = ctrl->max_entries;
+        fd = bpf_create_map_xattr(&map_attr);
+        if (fd < 0) {
+            goto err;
+        }
+        ctrl->map_fd = fd;
+        break;
+    case VIRTIO_NET_BPF_CMD_FREE_MAP:
+        close(ctrl->map_fd);
+        break;
+    case VIRTIO_NET_BPF_CMD_LOOKUP_ELEM:
+        err = bpf_map_lookup_elem(ctrl->map_fd, key, val);
+        break;
+    case VIRTIO_NET_BPF_CMD_GET_FIRST:
+        err = bpf_map_get_next_key(ctrl->map_fd, NULL, val);
+        break;
+    case VIRTIO_NET_BPF_CMD_GET_NEXT:
+        err = bpf_map_get_next_key(ctrl->map_fd, key, val);
+        break;
+    case VIRTIO_NET_BPF_CMD_UPDATE_ELEM:
+        err = bpf_map_update_elem(ctrl->map_fd, key, val, ctrl->flags);
+        break;
+    case VIRTIO_NET_BPF_CMD_DELETE_ELEM:
+        err = bpf_map_delete_elem(ctrl->map_fd, key);
+    default:
+        error_report("map operation not implemented %d", ctrl->cmd);
+        goto err;
+    }
+
+    if (err) {
+        goto err;
+    }
+
+    s = iov_from_buf(iov, iov_cnt, 0, ctrl, sizeof(*ctrl) + buf_len);
+    if (s != sizeof(*ctrl) + buf_len) {
+        error_report("failed to write map operation result");
+        goto err;
+    }
+
+    free(ctrl);
+    return VIRTIO_NET_OK;
+
+err:
+    if (ctrl) {
+        free(ctrl);
+    }
+#endif
+    return VIRTIO_NET_ERR;
+}
+
 static int virtio_net_handle_ebpf_prog(VirtIONet *n, struct iovec *iov,
                                        unsigned int iov_cnt)
 {
@@ -1053,6 +1139,8 @@ static int virtio_net_handle_ebpf(VirtIONet *n, uint8_t cmd,
 {
     if (cmd == VIRTIO_NET_CTRL_EBPF_PROG) {
         return virtio_net_handle_ebpf_prog(n, iov, iov_cnt);
+    } else if (cmd == VIRTIO_NET_CTRL_EBPF_MAP) {
+        return virtio_net_handle_ebpf_map(n, iov, iov_cnt);
     }
 
     return VIRTIO_NET_ERR;
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
index 83292c81bc..cca234e0e8 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -281,11 +281,34 @@ struct virtio_net_ctrl_ebpf_prog {
 	uint8_t insns[0];
 };
 
+struct virtio_net_ctrl_ebpf_map {
+	__virtio32 buf_len;
+	__virtio32 cmd;
+	__virtio32 map_type;
+	__virtio32 key_size;
+	__virtio32 value_size;
+	__virtio32 max_entries;
+	__virtio32 map_flags;
+	__virtio32 map_fd;
+	__virtio64 flags;
+	uint8_t buf[0];
+};
+
 #define VIRTIO_NET_CTRL_EBPF 	6
  #define VIRTIO_NET_CTRL_EBPF_PROG 1
+ #define VIRTIO_NET_CTRL_EBPF_MAP 2
 
 /* Commands for VIRTIO_NET_CTRL_EBPF_PROG */
 #define VIRTIO_NET_BPF_CMD_SET_OFFLOAD 1
 #define VIRTIO_NET_BPF_CMD_UNSET_OFFLOAD 2
 
+/* Commands for VIRTIO_NET_CTRL_EBPF_MAP */
+#define VIRTIO_NET_BPF_CMD_CREATE_MAP 1
+#define VIRTIO_NET_BPF_CMD_FREE_MAP 2
+#define VIRTIO_NET_BPF_CMD_UPDATE_ELEM 3
+#define VIRTIO_NET_BPF_CMD_LOOKUP_ELEM 4
+#define VIRTIO_NET_BPF_CMD_DELETE_ELEM 5
+#define VIRTIO_NET_BPF_CMD_GET_FIRST 6
+#define VIRTIO_NET_BPF_CMD_GET_NEXT 7
+
 #endif /* _LINUX_VIRTIO_NET_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC 0/3] Qemu: virtio-net XDP offload
  2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
                   ` (2 preceding siblings ...)
  2019-11-26 10:09 ` [RFC 3/3] virtio-net: add support for offloading an ebpf map Prashant Bhole
@ 2019-11-26 10:33 ` no-reply
  2019-11-27  1:27   ` Prashant Bhole
  2019-11-26 10:36 ` no-reply
  4 siblings, 1 reply; 7+ messages in thread
From: no-reply @ 2019-11-26 10:33 UTC (permalink / raw)
  To: prashantbhole.linux
  Cc: mst, jasowang, qemu-devel, songliubraving, jakub.kicinski, hawk,
	daniel, netdev, john.fastabend, ast, kafai, prashantbhole.linux,
	kvm, yhs, andriin, davem

Patchew URL: https://patchew.org/QEMU/20191126100914.5150-1-prashantbhole.linux@gmail.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC      ui/input-keymap.o
  CC      ui/input-legacy.o
  CC      ui/kbd-state.o
/tmp/qemu-test/src/net/tap-linux.c:34:21: fatal error: bpf/bpf.h: No such file or directory
 #include <bpf/bpf.h>
                     ^
compilation terminated.
---
  SIGN    pc-bios/optionrom/linuxboot.bin
  SIGN    pc-bios/optionrom/kvmvapic.bin
  BUILD   pc-bios/optionrom/linuxboot_dma.img
make: *** [net/tap-linux.o] Error 1
make: *** Waiting for unfinished jobs....
  BUILD   pc-bios/optionrom/pvh.img
  BUILD   pc-bios/optionrom/linuxboot_dma.raw
---
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=be849bfed02d4ea7b19f7746fe037bd5', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-3d2z3wl3/src/docker-src.2019-11-26-05.31.05.21708:/var/tmp/qemu:z,ro', 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=be849bfed02d4ea7b19f7746fe037bd5
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-3d2z3wl3/src'
make: *** [docker-run-test-quick@centos7] Error 2

real    1m56.447s
user    0m8.519s


The full log is available at
http://patchew.org/logs/20191126100914.5150-1-prashantbhole.linux@gmail.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC 0/3] Qemu: virtio-net XDP offload
  2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
                   ` (3 preceding siblings ...)
  2019-11-26 10:33 ` [RFC 0/3] Qemu: virtio-net XDP offload no-reply
@ 2019-11-26 10:36 ` no-reply
  4 siblings, 0 replies; 7+ messages in thread
From: no-reply @ 2019-11-26 10:36 UTC (permalink / raw)
  To: prashantbhole.linux
  Cc: mst, jasowang, qemu-devel, songliubraving, jakub.kicinski, hawk,
	daniel, netdev, john.fastabend, ast, kafai, prashantbhole.linux,
	kvm, yhs, andriin, davem

Patchew URL: https://patchew.org/QEMU/20191126100914.5150-1-prashantbhole.linux@gmail.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC      aarch64-softmmu/hw/arm/musicpal.o
  CC      aarch64-softmmu/hw/arm/netduino2.o
  CC      aarch64-softmmu/hw/arm/nseries.o
/tmp/qemu-test/src/hw/net/virtio-net.c:636:12: error: 'peer_attach_ebpf' defined but not used [-Werror=unused-function]
 static int peer_attach_ebpf(VirtIONet *n, int len, void *insns, uint8_t gpl)
            ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [/tmp/qemu-test/src/rules.mak:69: hw/net/virtio-net.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  CC      aarch64-softmmu/hw/arm/omap_sx1.o
  CC      aarch64-softmmu/hw/arm/palm.o
make: *** [Makefile:491: x86_64-softmmu/all] Error 2
make: *** Waiting for unfinished jobs....
  CC      aarch64-softmmu/hw/arm/gumstix.o
  CC      aarch64-softmmu/hw/arm/spitz.o
---
  CC      aarch64-softmmu/gdbstub-xml.o
  CC      aarch64-softmmu/trace/generated-helpers.o
  CC      aarch64-softmmu/target/arm/translate-sve.o
/tmp/qemu-test/src/hw/net/virtio-net.c:636:12: error: 'peer_attach_ebpf' defined but not used [-Werror=unused-function]
 static int peer_attach_ebpf(VirtIONet *n, int len, void *insns, uint8_t gpl)
            ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [/tmp/qemu-test/src/rules.mak:69: hw/net/virtio-net.o] Error 1
make: *** [Makefile:491: aarch64-softmmu/all] Error 2
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in <module>
    sys.exit(main())
---
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=5b6acc2ac7494ad6b59706c9dd26c3cd', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-4e2hnnd5/src/docker-src.2019-11-26-05.33.37.332:/var/tmp/qemu:z,ro', 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=5b6acc2ac7494ad6b59706c9dd26c3cd
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-4e2hnnd5/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real    2m24.967s
user    0m8.999s


The full log is available at
http://patchew.org/logs/20191126100914.5150-1-prashantbhole.linux@gmail.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC 0/3] Qemu: virtio-net XDP offload
  2019-11-26 10:33 ` [RFC 0/3] Qemu: virtio-net XDP offload no-reply
@ 2019-11-27  1:27   ` Prashant Bhole
  0 siblings, 0 replies; 7+ messages in thread
From: Prashant Bhole @ 2019-11-27  1:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, songliubraving, jakub.kicinski, hawk, daniel,
	netdev, john.fastabend, ast, kafai, kvm, yhs, andriin, davem



On 11/26/19 7:33 PM, no-reply@patchew.org wrote:
> Patchew URL: https://patchew.org/QEMU/20191126100914.5150-1-prashantbhole.linux@gmail.com/
> 
> 
> 
> Hi,
> 
> This series failed the docker-quick@centos7 build test. Please find the testing commands and
> their output below. If you have Docker installed, you can probably reproduce it
> locally.
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> make docker-image-centos7 V=1 NETWORK=1
> time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
> === TEST SCRIPT END ===
> 
>    CC      ui/input-keymap.o
>    CC      ui/input-legacy.o
>    CC      ui/kbd-state.o
> /tmp/qemu-test/src/net/tap-linux.c:34:21: fatal error: bpf/bpf.h: No such file or directory
>   #include <bpf/bpf.h>

Sorry, I missed to enclose it in #ifdef CONFIG_LIBBPF.
It should be fixed whenever I'll post next revision.


Prashant


>                       ^
> compilation terminated.
> ---
>    SIGN    pc-bios/optionrom/linuxboot.bin
>    SIGN    pc-bios/optionrom/kvmvapic.bin
>    BUILD   pc-bios/optionrom/linuxboot_dma.img
> make: *** [net/tap-linux.o] Error 1
> make: *** Waiting for unfinished jobs....
>    BUILD   pc-bios/optionrom/pvh.img
>    BUILD   pc-bios/optionrom/linuxboot_dma.raw
> ---
>      raise CalledProcessError(retcode, cmd)
> subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=be849bfed02d4ea7b19f7746fe037bd5', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-3d2z3wl3/src/docker-src.2019-11-26-05.31.05.21708:/var/tmp/qemu:z,ro', 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2.
> filter=--filter=label=com.qemu.instance.uuid=be849bfed02d4ea7b19f7746fe037bd5
> make[1]: *** [docker-run] Error 1
> make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-3d2z3wl3/src'
> make: *** [docker-run-test-quick@centos7] Error 2
> 
> real    1m56.447s
> user    0m8.519s
> 
> 
> The full log is available at
> http://patchew.org/logs/20191126100914.5150-1-prashantbhole.linux@gmail.com/testing.docker-quick@centos7/?type=message.
> ---
> Email generated automatically by Patchew [https://patchew.org/].
> Please send your feedback to patchew-devel@redhat.com
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-11-27  1:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-26 10:09 [RFC 0/3] Qemu: virtio-net XDP offload Prashant Bhole
2019-11-26 10:09 ` [RFC 1/3] configure: add libbpf support Prashant Bhole
2019-11-26 10:09 ` [RFC 2/3] virtio-net: add support for offloading XDP program Prashant Bhole
2019-11-26 10:09 ` [RFC 3/3] virtio-net: add support for offloading an ebpf map Prashant Bhole
2019-11-26 10:33 ` [RFC 0/3] Qemu: virtio-net XDP offload no-reply
2019-11-27  1:27   ` Prashant Bhole
2019-11-26 10:36 ` no-reply

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).