The filter-ubpf module able to load user defined ebpf program to handle network packet based on filter framework.
Signed-off-by: Zhang Chen <chen.zh...@intel.com> --- net/filter-ubpf.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ net/meson.build | 1 + 2 files changed, 150 insertions(+) create mode 100644 net/filter-ubpf.c diff --git a/net/filter-ubpf.c b/net/filter-ubpf.c new file mode 100644 index 0000000000..c63a021759 --- /dev/null +++ b/net/filter-ubpf.c @@ -0,0 +1,149 @@ +/* + * QEMU Userspace eBPF Support + * + * Copyright(C) 2022 Intel Corporation. + * + * Author: + * Zhang Chen <chen.zh...@intel.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "net/filter.h" +#include "net/net.h" +#include "qapi/error.h" +#include "qom/object.h" +#include "qemu/main-loop.h" +#include "qemu/error-report.h" +#include "trace.h" +#include "ebpf/ubpf.h" + +#define TYPE_FILTER_UBPF "filter-ubpf" +OBJECT_DECLARE_SIMPLE_TYPE(FiliterUbpfState, FILTER_UBPF) + +struct FiliterUbpfState { + NetFilterState parent_obj; + bool ip_mode; + char *handler; + UbpfState ubpf; +}; + +static ssize_t filter_ubpf_receive_iov(NetFilterState *nf, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb) +{ + /* TODO: handle packet by loaded userspace ebpf program */ + + return 0; +} + +static void filter_ubpf_cleanup(NetFilterState *nf) +{ + /* cleanup */ +} + +static void filter_ubpf_setup(NetFilterState *nf, Error **errp) +{ + FiliterUbpfState *s = FILTER_UBPF(nf); + + if (s->handler == NULL) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "filter-ubpf parameter"\ + " 'ubpf-handler' cannot be empty"); + return; + } + + qemu_ubpf_init_jit(&s->ubpf, true); + + if (qemu_ubpf_prepare(&s->ubpf, s->handler)) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE, "filter-ubpf parameter"\ + " 'ubpf-handler' cannot be load"); + return; + } +} + +static char *filter_ubpf_get_handler(Object *obj, Error **errp) +{ + FiliterUbpfState *s = FILTER_UBPF(obj); + + return g_strdup(s->handler); +} + +static void filter_ubpf_set_handler(Object *obj, + const char *value, + Error **errp) +{ + FiliterUbpfState *s = FILTER_UBPF(obj); + + g_free(s->handler); + s->handler = g_strdup(value); + if (!s->handler) { + error_setg(errp, "filter ubpf needs 'ubpf-handler' " + "property set"); + return; + } +} + +static bool filter_ubpf_get_mode(Object *obj, Error **errp) +{ + FiliterUbpfState *s = FILTER_UBPF(obj); + + return s->ip_mode; +} + +static void filter_ubpf_set_mode(Object *obj, bool value, Error **errp) +{ + FiliterUbpfState *s = FILTER_UBPF(obj); + + s->ip_mode = value; +} + +static void filter_ubpf_class_init(ObjectClass *oc, void *data) +{ + NetFilterClass *nfc = NETFILTER_CLASS(oc); + + object_class_property_add_str(oc, "ubpf-handler", + filter_ubpf_get_handler, + filter_ubpf_set_handler); + object_class_property_add_bool(oc, "ip-mode", + filter_ubpf_get_mode, + filter_ubpf_set_mode); + + nfc->setup = filter_ubpf_setup; + nfc->cleanup = filter_ubpf_cleanup; + nfc->receive_iov = filter_ubpf_receive_iov; +} + +static void filter_ubpf_init(Object *obj) +{ + FiliterUbpfState *s = FILTER_UBPF(obj); + + /* Filter-ubpf default is ip_mode */ + s->ip_mode = true; +} + +static void filter_ubpf_fini(Object *obj) +{ + /* do some thing */ +} + +static const TypeInfo filter_ubpf_info = { + .name = TYPE_FILTER_UBPF, + .parent = TYPE_NETFILTER, + .class_init = filter_ubpf_class_init, + .instance_init = filter_ubpf_init, + .instance_finalize = filter_ubpf_fini, + .instance_size = sizeof(FiliterUbpfState), +}; + +static void register_types(void) +{ + type_register_static(&filter_ubpf_info); +} + +type_init(register_types); diff --git a/net/meson.build b/net/meson.build index 754e2d1d40..177078fa7a 100644 --- a/net/meson.build +++ b/net/meson.build @@ -14,6 +14,7 @@ softmmu_ss.add(files( 'queue.c', 'socket.c', 'util.c', + 'filter-ubpf.c', )) softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('filter-replay.c')) -- 2.25.1