/*
 * e_bpf.c	BPF exec proxy
 *
 *		This program is free software; you can distribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Daniel Borkmann <daniel@iogearbox.net>
 */

#include <stdio.h>
#include <unistd.h>

#include "utils.h"

#include "tc_util.h"
#include "tc_bpf.h"

#include "bpf_elf.h"
#include "bpf_scm.h"

#define BPF_DEFAULT_CMD	"/bin/sh"

static char *argv_default[] = { BPF_DEFAULT_CMD, NULL };

static void explain(void)
{
	fprintf(stderr, "Usage: ... bpf [ import UDS_FILE ] [ run CMD ]\n");
	fprintf(stderr, "       ... bpf [ debug ]\n");
	fprintf(stderr, "       ... bpf [ graft MAP_FILE ] [ key KEY ]\n");
	fprintf(stderr, "          `... [ object-file OBJ_FILE ] [ type TYPE ] [ section NAME ] [ verbose ]\n");
	fprintf(stderr, "          `... [ object-pinned PROG_FILE ]\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "Where UDS_FILE provides the name of a unix domain socket file\n");
	fprintf(stderr, "to import eBPF maps and the optional CMD denotes the command\n");
	fprintf(stderr, "to be executed (default: \'%s\').\n", BPF_DEFAULT_CMD);
	fprintf(stderr, "Where MAP_FILE points to a pinned map, OBJ_FILE to an object file\n");
	fprintf(stderr, "and PROG_FILE to a pinned program. TYPE can be {cls, act}, where\n");
	fprintf(stderr, "\'cls\' is default. KEY is optional and can be inferred from the\n");
	fprintf(stderr, "section name, otherwise it needs to be provided.\n");
}

static int bpf_num_env_entries(void)
{
	char **envp;
	int num;

	for (num = 0, envp = environ; *envp != NULL; envp++)
		num++;
	return num;
}

static int parse_bpf(struct exec_util *eu, int argc, char **argv)
{
	char **argv_run = argv_default, **envp_run, *tmp;
	int ret, i, env_old, env_num, env_map;
	const char *bpf_uds_name = NULL;
	int fds[BPF_SCM_MAX_FDS] = {};
	struct bpf_map_aux aux = {};

	if (argc == 0)
		return 0;

	while (argc > 0) {
		if (matches(*argv, "run") == 0) {
			NEXT_ARG();
			argv_run = argv;
			break;
		} else if (matches(*argv, "import") == 0) {
			NEXT_ARG();
			bpf_uds_name = *argv;
		} else if (matches(*argv, "debug") == 0 ||
			   matches(*argv, "dbg") == 0) {
			if (bpf_trace_pipe())
				fprintf(stderr,
					"No trace pipe, tracefs not mounted?\n");
			return -1;
		} else if (matches(*argv, "graft") == 0) {
			const char *bpf_map_path;
			bool has_key = false;
			uint32_t key;

			NEXT_ARG();
			bpf_map_path = *argv;
			NEXT_ARG();
			if (matches(*argv, "key") == 0) {
				NEXT_ARG();
				if (get_unsigned(&key, *argv, 0)) {
					fprintf(stderr, "Illegal \"key\"\n");
					return -1;
				}
				has_key = true;
				NEXT_ARG();
			}
			return bpf_graft_map(bpf_map_path, has_key ?
					     &key : NULL, argc, argv);
		} else {
			explain();
			return -1;
		}

		NEXT_ARG_FWD();
	}

	if (!bpf_uds_name) {
		fprintf(stderr, "bpf: No import parameter provided!\n");
		explain();
		return -1;
	}

	if (argv_run != argv_default && argc == 0) {
		fprintf(stderr, "bpf: No run command provided!\n");
		explain();
		return -1;
	}

	ret = bpf_recv_map_fds(bpf_uds_name, fds, &aux, ARRAY_SIZE(fds));
	if (ret < 0) {
		fprintf(stderr, "bpf: Could not receive fds!\n");
		return -1;
	}

	if (aux.num_ent == 0) {
		envp_run = environ;
		goto out;
	}

	env_old = bpf_num_env_entries();
	env_num = env_old + aux.num_ent + 2;
	env_map = env_old + 1;

	envp_run = malloc(sizeof(*envp_run) * env_num);
	if (!envp_run) {
		fprintf(stderr, "bpf: No memory left to allocate env!\n");
		goto err;
	}

	for (i = 0; i < env_old; i++)
		envp_run[i] = environ[i];

	ret = asprintf(&tmp, "BPF_NUM_MAPS=%u", aux.num_ent);
	if (ret < 0)
		goto err_free;

	envp_run[env_old] = tmp;

	for (i = env_map; i < env_num - 1; i++) {
		ret = asprintf(&tmp, "BPF_MAP%u=%u",
			       aux.ent[i - env_map].id,
			       fds[i - env_map]);
		if (ret < 0)
			goto err_free_env;

		envp_run[i] = tmp;
	}

	envp_run[env_num - 1] = NULL;
out:
	return execvpe(argv_run[0], argv_run, envp_run);

err_free_env:
	for (--i; i >= env_old; i--)
		free(envp_run[i]);
err_free:
	free(envp_run);
err:
	for (i = 0; i < aux.num_ent; i++)
		close(fds[i]);
	return -1;
}

struct exec_util bpf_exec_util = {
	.id		= "bpf",
	.parse_eopt	= parse_bpf,
};
