/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
/* Copyright (c) 2021 Facebook */
#ifndef __SKEL_INTERNAL_H
#define __SKEL_INTERNAL_H

#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>

/* This file is a base header for auto-generated *.lskel.h files.
 * Its contents will change and may become part of auto-generation in the future.
 *
 * The layout of bpf_[map|prog]_desc and bpf_loader_ctx is feature dependent
 * and will change from one version of libbpf to another and features
 * requested during loader program generation.
 */
struct bpf_map_desc {
	union {
		/* input for the loader prog */
		struct {
			__aligned_u64 initial_value;
			__u32 max_entries;
		};
		/* output of the loader prog */
		struct {
			int map_fd;
		};
	};
};
struct bpf_prog_desc {
	int prog_fd;
};

struct bpf_loader_ctx {
	size_t sz;
	__u32 log_level;
	__u32 log_size;
	__u64 log_buf;
};

struct bpf_load_and_run_opts {
	struct bpf_loader_ctx *ctx;
	const void *data;
	const void *insns;
	__u32 data_sz;
	__u32 insns_sz;
	const char *errstr;
};

static inline int skel_sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
			  unsigned int size)
{
	return syscall(__NR_bpf, cmd, attr, size);
}

static inline int skel_closenz(int fd)
{
	if (fd > 0)
		return close(fd);
	return -EINVAL;
}

static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
{
	int map_fd = -1, prog_fd = -1, key = 0, err;
	union bpf_attr attr;

	map_fd = bpf_create_map_name(BPF_MAP_TYPE_ARRAY, "__loader.map", 4,
				     opts->data_sz, 1, 0);
	if (map_fd < 0) {
		opts->errstr = "failed to create loader map";
		err = -errno;
		goto out;
	}

	err = bpf_map_update_elem(map_fd, &key, opts->data, 0);
	if (err < 0) {
		opts->errstr = "failed to update loader map";
		err = -errno;
		goto out;
	}

	memset(&attr, 0, sizeof(attr));
	attr.prog_type = BPF_PROG_TYPE_SYSCALL;
	attr.insns = (long) opts->insns;
	attr.insn_cnt = opts->insns_sz / sizeof(struct bpf_insn);
	attr.license = (long) "Dual BSD/GPL";
	memcpy(attr.prog_name, "__loader.prog", sizeof("__loader.prog"));
	attr.fd_array = (long) &map_fd;
	attr.log_level = opts->ctx->log_level;
	attr.log_size = opts->ctx->log_size;
	attr.log_buf = opts->ctx->log_buf;
	attr.prog_flags = BPF_F_SLEEPABLE;
	prog_fd = skel_sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
	if (prog_fd < 0) {
		opts->errstr = "failed to load loader prog";
		err = -errno;
		goto out;
	}

	memset(&attr, 0, sizeof(attr));
	attr.test.prog_fd = prog_fd;
	attr.test.ctx_in = (long) opts->ctx;
	attr.test.ctx_size_in = opts->ctx->sz;
	err = skel_sys_bpf(BPF_PROG_RUN, &attr, sizeof(attr));
	if (err < 0 || (int)attr.test.retval < 0) {
		opts->errstr = "failed to execute loader prog";
		if (err < 0) {
			err = -errno;
		} else {
			err = (int)attr.test.retval;
			errno = -err;
		}
		goto out;
	}
	err = 0;
out:
	if (map_fd >= 0)
		close(map_fd);
	if (prog_fd >= 0)
		close(prog_fd);
	return err;
}

#endif
