/*
 * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"

#ifdef HAVE_LINUX_BPF_H
# include <linux/bpf.h>
#endif

#include "xlat/bpf_commands.h"
#include "xlat/bpf_map_types.h"
#include "xlat/bpf_prog_types.h"
#include "xlat/bpf_map_update_elem_flags.h"

static int
bpf_map_create(struct tcb *tcp, const long addr, unsigned int size)
{
	struct {
		uint32_t map_type, key_size, value_size, max_entries;
	} attr = {};

	if (!size) {
		printaddr(addr);
		return RVAL_DECODED | RVAL_FD;
	}
	if (size > sizeof(attr))
		size = sizeof(attr);
	if (umoven_or_printaddr(tcp, addr, size, &attr))
		return RVAL_DECODED | RVAL_FD;

	tprints("{map_type=");
	printxval(bpf_map_types, attr.map_type, "BPF_MAP_TYPE_???");
	tprintf(", key_size=%u, value_size=%u, max_entries=%u}",
		attr.key_size, attr.value_size, attr.max_entries);

	return RVAL_DECODED | RVAL_FD;
}

static void
bpf_map_update_elem(struct tcb *tcp, const long addr, unsigned int size)
{
	struct {
		uint32_t map_fd;
		uint64_t ATTRIBUTE_ALIGNED(8) key;
		uint64_t ATTRIBUTE_ALIGNED(8) value;
		uint64_t flags;
	} attr = {};

	if (!size) {
		printaddr(addr);
		return;
	}
	if (size > sizeof(attr))
		size = sizeof(attr);
	if (umoven_or_printaddr(tcp, addr, size, &attr))
		return;

	tprints("{map_fd=");
	printfd(tcp, attr.map_fd);
	tprintf(", key=%#" PRIx64 ", value=%#" PRIx64 ", flags=",
		attr.key, attr.value);
	printxval(bpf_map_update_elem_flags, attr.flags, "BPF_???");
	tprints("}");
}

static void
bpf_map_delete_elem(struct tcb *tcp, const long addr, unsigned int size)
{
	struct {
		uint32_t map_fd;
		uint64_t ATTRIBUTE_ALIGNED(8) key;
	} attr = {};

	if (!size) {
		printaddr(addr);
		return;
	}
	if (size > sizeof(attr))
		size = sizeof(attr);
	if (umoven_or_printaddr(tcp, addr, size, &attr))
		return;

	tprints("{map_fd=");
	printfd(tcp, attr.map_fd);
	tprintf(", key=%#" PRIx64 "}", attr.key);
}

static int
bpf_map_io(struct tcb *tcp, const long addr, unsigned int size, const char *text)
{
	struct bpf_io_elem_struct {
		uint32_t map_fd;
		uint64_t ATTRIBUTE_ALIGNED(8) key;
		uint64_t ATTRIBUTE_ALIGNED(8) value;
	} attr = {};

	if (exiting(tcp)) {
		if (!syserror(tcp) && !umove_or_printaddr(tcp, addr, &attr))
			tprintf(", %s=%#" PRIx64, text, attr.value);
		tprints("}");
		return RVAL_DECODED;
	}

	if (!size) {
		printaddr(addr);
		return RVAL_DECODED;
	}
	if (size > sizeof(attr))
		size = sizeof(attr);
	if (umoven_or_printaddr(tcp, addr, size, &attr))
		return RVAL_DECODED;

	tprints("{map_fd=");
	printfd(tcp, attr.map_fd);
	tprintf(", key=%#" PRIx64, attr.key);

	return 0;
}

static int
bpf_prog_load(struct tcb *tcp, const long addr, unsigned int size)
{
	struct {
		uint32_t prog_type, insn_cnt;
		uint64_t ATTRIBUTE_ALIGNED(8) insns, license;
		uint32_t log_level, log_size;
		uint64_t ATTRIBUTE_ALIGNED(8) log_buf;
		uint32_t kern_version;
	} attr = {};

	if (!size) {
		printaddr(addr);
		return RVAL_DECODED | RVAL_FD;
	}
	if (size > sizeof(attr))
		size = sizeof(attr);
	if (umoven_or_printaddr(tcp, addr, size, &attr))
		return RVAL_DECODED | RVAL_FD;

	tprints("{prog_type=");
	printxval(bpf_prog_types, attr.prog_type, "BPF_PROG_TYPE_???");
	tprintf(", insn_cnt=%u, insns=%#" PRIx64 ", license=",
		attr.insn_cnt, attr.insns);
	printstr(tcp, attr.license, -1);
	tprintf(", log_level=%u, log_size=%u, log_buf=%#" PRIx64 ", kern_version=%u}",
		attr.log_level, attr.log_size, attr.log_buf, attr.kern_version);

	return RVAL_DECODED | RVAL_FD;
}

SYS_FUNC(bpf)
{
	const int cmd = tcp->u_arg[0];
	const long addr = tcp->u_arg[1];
	const unsigned int size = tcp->u_arg[2];
	int rc = RVAL_DECODED;

	if (entering(tcp)) {
		printxval(bpf_commands, cmd, "BPF_???");
		tprints(", ");
	}

	switch (cmd) {
	case BPF_MAP_CREATE:
		rc = bpf_map_create(tcp, addr, size);
		break;
	case BPF_MAP_LOOKUP_ELEM:
		rc = bpf_map_io(tcp, addr, size, "value");
		break;
	case BPF_MAP_UPDATE_ELEM:
		bpf_map_update_elem(tcp, addr, size);
		break;
	case BPF_MAP_DELETE_ELEM:
		bpf_map_delete_elem(tcp, addr, size);
		break;
	case BPF_MAP_GET_NEXT_KEY:
		rc = bpf_map_io(tcp, addr, size, "next_key");
		break;
	case BPF_PROG_LOAD:
		rc = bpf_prog_load(tcp, addr, size);
		break;
	default:
		printaddr(addr);
		break;
	}

	if (rc & RVAL_DECODED)
		tprintf(", %u", size);

	return rc;
}
