[RFC PATCH 3/4] qemu_interface: Added routine for loading the eBPF objects.

Andrew Melnychenko posted 4 patches 2 years, 4 months ago
There is a newer version of this series
[RFC PATCH 3/4] qemu_interface: Added routine for loading the eBPF objects.
Posted by Andrew Melnychenko 2 years, 4 months ago
Also, added dependencies for libbpf with bpf option.

Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
---
 meson.build               |  6 ++++++
 meson_options.txt         |  1 +
 src/qemu/meson.build      |  1 +
 src/qemu/qemu_interface.c | 42 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_interface.h |  4 ++++
 5 files changed, 54 insertions(+)

diff --git a/meson.build b/meson.build
index de23fbda1e..b68e916246 100644
--- a/meson.build
+++ b/meson.build
@@ -1381,6 +1381,11 @@ if yajl_dep.found()
   conf.set('WITH_YAJL', 1)
 endif
 
+bpf_version = '1.1.0'
+bpf_dep = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'))
+if bpf_dep.found()
+    conf.set('WITH_BPF', 1)
+endif
 
 # generic build dependencies checks
 
@@ -2269,6 +2274,7 @@ libs_summary = {
   'udev': udev_dep.found(),
   'xdr': xdr_dep.found(),
   'yajl': yajl_dep.found(),
+  'bpf': bpf_dep.found(),
 }
 summary(libs_summary, section: 'Libraries', bool_yn: true)
 
diff --git a/meson_options.txt b/meson_options.txt
index 7c428a9eb0..092b2efe06 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -44,6 +44,7 @@ option('udev', type: 'feature', value: 'auto', description: 'udev support')
 option('wireshark_dissector', type: 'feature', value: 'auto', description: 'wireshark support')
 option('wireshark_plugindir', type: 'string', value: '', description: 'wireshark plugins directory for use when installing wireshark plugin')
 option('yajl', type: 'feature', value: 'auto', description: 'yajl support')
+option('bpf', type: 'feature', value: 'auto', description: 'qemu libbpf support')
 
 
 # build driver options
diff --git a/src/qemu/meson.build b/src/qemu/meson.build
index 64c62e584f..afd9133ae0 100644
--- a/src/qemu/meson.build
+++ b/src/qemu/meson.build
@@ -105,6 +105,7 @@ if conf.has('WITH_QEMU')
       selinux_dep,
       src_dep,
       xdr_dep,
+      bpf_dep,
     ],
     include_directories: [
       conf_inc_dir,
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index 8856bb95a8..a3a43a43c5 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -36,6 +36,7 @@
 
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <bpf/libbpf.h>
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -763,3 +764,44 @@ qemuInterfaceOpenVhostNet(virDomainObj *vm,
     virDomainAuditNetDevice(vm->def, net, vhostnet_path, vhostfdSize);
     return 0;
 }
+
+
+int qemuInterfaceLoadEbpf(const void *ebpfObject, size_t ebpfSize, void **retLibbpfObj, int *fds, int nfds) {
+    int err = 0;
+    int i = 0;
+
+    struct bpf_object *obj = bpf_object__open_mem(ebpfObject, ebpfSize, NULL);
+    err = libbpf_get_error(obj);
+    if(err) {
+        return -1;
+    }
+
+    struct bpf_program *prog;
+    struct bpf_map *map;
+
+    err = bpf_object__load(obj);
+    if (err) {
+        return -1;
+    }
+
+    bpf_object__for_each_program(prog, obj) {
+        fds[i] = bpf_program__fd(prog);
+        ++i;
+    }
+
+    bpf_object__for_each_map(map, obj) {
+        fds[i] = bpf_map__fd(map);
+        ++i;
+    }
+
+    *retLibbpfObj = obj;
+
+    return i;
+}
+
+
+void qemuInterfaceCloseEbpf(void *libbpfObj)
+{
+    if(libbpfObj)
+        bpf_object__close(libbpfObj);
+}
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index 6eed3e6bd7..dbc1fd625c 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -55,3 +55,7 @@ int qemuInterfaceOpenVhostNet(virDomainObj *def,
 
 int qemuInterfacePrepareSlirp(virQEMUDriver *driver,
                               virDomainNetDef *net);
+
+int qemuInterfaceLoadEbpf(const void *ebpfObject, size_t ebpfSize, void **retLibbpfObj, int *fds, int nfds);
+
+void qemuInterfaceCloseEbpf(void *libbpfObj);
-- 
2.42.0
Re: [RFC PATCH 3/4] qemu_interface: Added routine for loading the eBPF objects.
Posted by Peter Krempa 2 years, 4 months ago
On Mon, Oct 09, 2023 at 09:16:13 +0300, Andrew Melnychenko wrote:
> Also, added dependencies for libbpf with bpf option.
> 
> Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> ---
>  meson.build               |  6 ++++++
>  meson_options.txt         |  1 +
>  src/qemu/meson.build      |  1 +
>  src/qemu/qemu_interface.c | 42 +++++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_interface.h |  4 ++++
>  5 files changed, 54 insertions(+)

Yet again fails to compile:

a.p/qemu_interface.c.o -c ../../../libvirt/src/qemu/qemu_interface.c
../../../libvirt/src/qemu/qemu_interface.c: In function ‘qemuInterfaceLoadEbpf’:
../../../libvirt/src/qemu/qemu_interface.c:779:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
  779 |     struct bpf_program *prog;
      |     ^~~~~~
../../../libvirt/src/qemu/qemu_interface.c:769:103: error: unused parameter ‘nfds’ [-Werror=unused-parameter]
  769 | int qemuInterfaceLoadEbpf(const void *ebpfObject, size_t ebpfSize, void **retLibbpfObj, int *fds, int nfds) {
      |                                                                                                   ~~~~^~~~

Fixing that also shows that the syntax-check rules were also broken.

> 
> diff --git a/meson.build b/meson.build
> index de23fbda1e..b68e916246 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1381,6 +1381,11 @@ if yajl_dep.found()
>    conf.set('WITH_YAJL', 1)
>  endif
>  
> +bpf_version = '1.1.0'
> +bpf_dep = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'))
> +if bpf_dep.found()
> +    conf.set('WITH_BPF', 1)
> +endif
>  
>  # generic build dependencies checks
>  
> @@ -2269,6 +2274,7 @@ libs_summary = {
>    'udev': udev_dep.found(),
>    'xdr': xdr_dep.found(),
>    'yajl': yajl_dep.found(),
> +  'bpf': bpf_dep.found(),
>  }
>  summary(libs_summary, section: 'Libraries', bool_yn: true)
>  
> diff --git a/meson_options.txt b/meson_options.txt
> index 7c428a9eb0..092b2efe06 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -44,6 +44,7 @@ option('udev', type: 'feature', value: 'auto', description: 'udev support')
>  option('wireshark_dissector', type: 'feature', value: 'auto', description: 'wireshark support')
>  option('wireshark_plugindir', type: 'string', value: '', description: 'wireshark plugins directory for use when installing wireshark plugin')
>  option('yajl', type: 'feature', value: 'auto', description: 'yajl support')
> +option('bpf', type: 'feature', value: 'auto', description: 'qemu libbpf support')
>  
>  
>  # build driver options
> diff --git a/src/qemu/meson.build b/src/qemu/meson.build
> index 64c62e584f..afd9133ae0 100644
> --- a/src/qemu/meson.build
> +++ b/src/qemu/meson.build
> @@ -105,6 +105,7 @@ if conf.has('WITH_QEMU')
>        selinux_dep,
>        src_dep,
>        xdr_dep,
> +      bpf_dep,
>      ],
>      include_directories: [
>        conf_inc_dir,
> diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
> index 8856bb95a8..a3a43a43c5 100644
> --- a/src/qemu/qemu_interface.c
> +++ b/src/qemu/qemu_interface.c
> @@ -36,6 +36,7 @@
>  
>  #include <sys/stat.h>
>  #include <fcntl.h>
> +#include <bpf/libbpf.h>
>  
>  #define VIR_FROM_THIS VIR_FROM_QEMU
>  
> @@ -763,3 +764,44 @@ qemuInterfaceOpenVhostNet(virDomainObj *vm,
>      virDomainAuditNetDevice(vm->def, net, vhostnet_path, vhostfdSize);
>      return 0;
>  }
> +
> +

Please document this function. It's not very obvious what it does on the
first glance.

> +int qemuInterfaceLoadEbpf(const void *ebpfObject, size_t ebpfSize, void **retLibbpfObj, int *fds, int nfds) {
> +    int err = 0;
> +    int i = 0;
> +
> +    struct bpf_object *obj = bpf_object__open_mem(ebpfObject, ebpfSize, NULL);

This is compiled regardless of 'WITH_BPF' flag ...

> +    err = libbpf_get_error(obj);
> +    if(err) {
> +        return -1;
> +    }