/*
 * eBPF RSS loader
 *
 * Developed by Daynix Computing LTD (http://www.daynix.com)
 *
 * Authors:
 *  Andrew Melnychenko <andrew@daynix.com>
 *  Yuri Benditovich <yuri.benditovich@daynix.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/qapi-types-misc.h"
#include "qapi/qapi-commands-ebpf.h"

#include <bpf/libbpf.h>
#include <bpf/bpf.h>

#include "hw/virtio/virtio-net.h" /* VIRTIO_NET_RSS_MAX_TABLE_LEN */

#include "ebpf/ebpf_rss.h"
#include "ebpf/rss.bpf.skeleton.h"
#include "ebpf/ebpf.h"

void ebpf_rss_init(struct EBPFRSSContext *ctx)
{
    if (ctx != NULL) {
        ctx->obj = NULL;
        ctx->program_fd = -1;
        ctx->map_configuration = -1;
        ctx->map_toeplitz_key = -1;
        ctx->map_indirections_table = -1;

        ctx->mmap_configuration = NULL;
        ctx->mmap_toeplitz_key = NULL;
        ctx->mmap_indirections_table = NULL;
    }
}

bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx)
{
    return ctx != NULL && (ctx->obj != NULL || ctx->program_fd != -1);
}

static bool ebpf_rss_mmap(struct EBPFRSSContext *ctx)
{
    if (!ebpf_rss_is_loaded(ctx)) {
        return false;
    }

    ctx->mmap_configuration = mmap(NULL, qemu_real_host_page_size(),
                                   PROT_READ | PROT_WRITE, MAP_SHARED,
                                   ctx->map_configuration, 0);
    if (ctx->mmap_configuration == MAP_FAILED) {
        return false;
    }
    ctx->mmap_toeplitz_key = mmap(NULL, qemu_real_host_page_size(),
                                   PROT_READ | PROT_WRITE, MAP_SHARED,
                                   ctx->map_toeplitz_key, 0);
    if (ctx->mmap_toeplitz_key == MAP_FAILED) {
        goto toeplitz_fail;
    }
    ctx->mmap_indirections_table = mmap(NULL, qemu_real_host_page_size(),
                                   PROT_READ | PROT_WRITE, MAP_SHARED,
                                   ctx->map_indirections_table, 0);
    if (ctx->mmap_indirections_table == MAP_FAILED) {
        goto indirection_fail;
    }

    return true;

indirection_fail:
    munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
    ctx->mmap_toeplitz_key = NULL;
toeplitz_fail:
    munmap(ctx->mmap_configuration, qemu_real_host_page_size());
    ctx->mmap_configuration = NULL;

    ctx->mmap_indirections_table = NULL;
    return false;
}

static void ebpf_rss_munmap(struct EBPFRSSContext *ctx)
{
    if (!ebpf_rss_is_loaded(ctx)) {
        return;
    }

    munmap(ctx->mmap_indirections_table, qemu_real_host_page_size());
    munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
    munmap(ctx->mmap_configuration, qemu_real_host_page_size());

    ctx->mmap_configuration = NULL;
    ctx->mmap_toeplitz_key = NULL;
    ctx->mmap_indirections_table = NULL;
}

bool ebpf_rss_load(struct EBPFRSSContext *ctx)
{
    struct rss_bpf *rss_bpf_ctx;

    if (ebpf_rss_is_loaded(ctx)) {
        return false;
    }

    rss_bpf_ctx = rss_bpf__open();
    if (rss_bpf_ctx == NULL) {
        goto error;
    }

    bpf_program__set_type(rss_bpf_ctx->progs.tun_rss_steering_prog, BPF_PROG_TYPE_SOCKET_FILTER);

    if (rss_bpf__load(rss_bpf_ctx)) {
        goto error;
    }

    ctx->obj = rss_bpf_ctx;
    ctx->program_fd = bpf_program__fd(
            rss_bpf_ctx->progs.tun_rss_steering_prog);
    ctx->map_configuration = bpf_map__fd(
            rss_bpf_ctx->maps.tap_rss_map_configurations);
    ctx->map_indirections_table = bpf_map__fd(
            rss_bpf_ctx->maps.tap_rss_map_indirection_table);
    ctx->map_toeplitz_key = bpf_map__fd(
            rss_bpf_ctx->maps.tap_rss_map_toeplitz_key);

    if (!ebpf_rss_mmap(ctx)) {
        goto error;
    }

    return true;
error:
    rss_bpf__destroy(rss_bpf_ctx);
    ctx->obj = NULL;
    ctx->program_fd = -1;
    ctx->map_configuration = -1;
    ctx->map_toeplitz_key = -1;
    ctx->map_indirections_table = -1;

    return false;
}

bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
                       int config_fd, int toeplitz_fd, int table_fd)
{
    if (ebpf_rss_is_loaded(ctx)) {
        return false;
    }

    if (program_fd < 0 || config_fd < 0 || toeplitz_fd < 0 || table_fd < 0) {
        return false;
    }

    ctx->program_fd = program_fd;
    ctx->map_configuration = config_fd;
    ctx->map_toeplitz_key = toeplitz_fd;
    ctx->map_indirections_table = table_fd;

    if (!ebpf_rss_mmap(ctx)) {
        ctx->program_fd = -1;
        ctx->map_configuration = -1;
        ctx->map_toeplitz_key = -1;
        ctx->map_indirections_table = -1;
        return false;
    }

    return true;
}

static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
                                struct EBPFRSSConfig *config)
{
    if (!ebpf_rss_is_loaded(ctx)) {
        return false;
    }

    memcpy(ctx->mmap_configuration, config, sizeof(*config));
    return true;
}

static bool ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
                                            uint16_t *indirections_table,
                                            size_t len)
{
    if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
       len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
        return false;
    }

    memcpy(ctx->mmap_indirections_table, indirections_table,
            sizeof(*indirections_table) * len);
    return true;
}

static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
                                     uint8_t *toeplitz_key)
{
    /* prepare toeplitz key */
    uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};

    if (!ebpf_rss_is_loaded(ctx) || toeplitz_key == NULL) {
        return false;
    }
    memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
    *(uint32_t *)toe = ntohl(*(uint32_t *)toe);

    memcpy(ctx->mmap_toeplitz_key, toe, VIRTIO_NET_RSS_MAX_KEY_SIZE);
    return true;
}

bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
                      uint16_t *indirections_table, uint8_t *toeplitz_key)
{
    if (!ebpf_rss_is_loaded(ctx) || config == NULL ||
        indirections_table == NULL || toeplitz_key == NULL) {
        return false;
    }

    if (!ebpf_rss_set_config(ctx, config)) {
        return false;
    }

    if (!ebpf_rss_set_indirections_table(ctx, indirections_table,
                                      config->indirections_len)) {
        return false;
    }

    if (!ebpf_rss_set_toepliz_key(ctx, toeplitz_key)) {
        return false;
    }

    return true;
}

void ebpf_rss_unload(struct EBPFRSSContext *ctx)
{
    if (!ebpf_rss_is_loaded(ctx)) {
        return;
    }

    ebpf_rss_munmap(ctx);

    if (ctx->obj) {
        rss_bpf__destroy(ctx->obj);
    } else {
        close(ctx->program_fd);
        close(ctx->map_configuration);
        close(ctx->map_toeplitz_key);
        close(ctx->map_indirections_table);
    }

    ctx->obj = NULL;
    ctx->program_fd = -1;
    ctx->map_configuration = -1;
    ctx->map_toeplitz_key = -1;
    ctx->map_indirections_table = -1;
}

ebpf_binary_init(EBPF_PROGRAMID_RSS, rss_bpf__elf_bytes)
