// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */

#include <errno.h>
#include <fcntl.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <net/if.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <bpf/bpf.h>
#include <bpf/btf.h>
#include <bpf/hashmap.h>

#include "json_writer.h"
#include "main.h"

static struct hashmap *map_table;

static bool map_is_per_cpu(__u32 type)
{
	return type == BPF_MAP_TYPE_PERCPU_HASH ||
	       type == BPF_MAP_TYPE_PERCPU_ARRAY ||
	       type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
	       type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
}

static bool map_is_map_of_maps(__u32 type)
{
	return type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
	       type == BPF_MAP_TYPE_HASH_OF_MAPS;
}

static bool map_is_map_of_progs(__u32 type)
{
	return type == BPF_MAP_TYPE_PROG_ARRAY;
}

static int map_type_from_str(const char *type)
{
	const char *map_type_str;
	unsigned int i;

	for (i = 0; ; i++) {
		map_type_str = libbpf_bpf_map_type_str(i);
		if (!map_type_str)
			break;

		/* Don't allow prefixing in case of possible future shadowing */
		if (!strcmp(map_type_str, type))
			return i;
	}
	return -1;
}

static void *alloc_value(struct bpf_map_info *info)
{
	if (map_is_per_cpu(info->type))
		return malloc(round_up(info->value_size, 8) *
			      get_possible_cpus());
	else
		return malloc(info->value_size);
}

static int do_dump_btf(const struct btf_dumper *d,
		       struct bpf_map_info *map_info, void *key,
		       void *value)
{
	__u32 value_id;
	int ret = 0;

	/* start of key-value pair */
	jsonw_start_object(d->jw);

	if (map_info->btf_key_type_id) {
		jsonw_name(d->jw, "key");

		ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
		if (ret)
			goto err_end_obj;
	}

	value_id = map_info->btf_vmlinux_value_type_id ?
		: map_info->btf_value_type_id;

	if (!map_is_per_cpu(map_info->type)) {
		jsonw_name(d->jw, "value");
		ret = btf_dumper_type(d, value_id, value);
	} else {
		unsigned int i, n, step;

		jsonw_name(d->jw, "values");
		jsonw_start_array(d->jw);
		n = get_possible_cpus();
		step = round_up(map_info->value_size, 8);
		for (i = 0; i < n; i++) {
			jsonw_start_object(d->jw);
			jsonw_int_field(d->jw, "cpu", i);
			jsonw_name(d->jw, "value");
			ret = btf_dumper_type(d, value_id, value + i * step);
			jsonw_end_object(d->jw);
			if (ret)
				break;
		}
		jsonw_end_array(d->jw);
	}

err_end_obj:
	/* end of key-value pair */
	jsonw_end_object(d->jw);

	return ret;
}

static json_writer_t *get_btf_writer(void)
{
	json_writer_t *jw = jsonw_new(stdout);

	if (!jw)
		return NULL;
	jsonw_pretty(jw, true);

	return jw;
}

static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
			     unsigned char *value, struct btf *btf)
{
	jsonw_start_object(json_wtr);

	if (!map_is_per_cpu(info->type)) {
		jsonw_name(json_wtr, "key");
		print_hex_data_json(key, info->key_size);
		jsonw_name(json_wtr, "value");
		print_hex_data_json(value, info->value_size);
		if (btf) {
			struct btf_dumper d = {
				.btf = btf,
				.jw = json_wtr,
				.is_plain_text = false,
			};

			jsonw_name(json_wtr, "formatted");
			do_dump_btf(&d, info, key, value);
		}
	} else {
		unsigned int i, n, step;

		n = get_possible_cpus();
		step = round_up(info->value_size, 8);

		jsonw_name(json_wtr, "key");
		print_hex_data_json(key, info->key_size);

		jsonw_name(json_wtr, "values");
		jsonw_start_array(json_wtr);
		for (i = 0; i < n; i++) {
			jsonw_start_object(json_wtr);

			jsonw_int_field(json_wtr, "cpu", i);

			jsonw_name(json_wtr, "value");
			print_hex_data_json(value + i * step,
					    info->value_size);

			jsonw_end_object(json_wtr);
		}
		jsonw_end_array(json_wtr);
		if (btf) {
			struct btf_dumper d = {
				.btf = btf,
				.jw = json_wtr,
				.is_plain_text = false,
			};

			jsonw_name(json_wtr, "formatted");
			do_dump_btf(&d, info, key, value);
		}
	}

	jsonw_end_object(json_wtr);
}

static void
print_entry_error_msg(struct bpf_map_info *info, unsigned char *key,
		      const char *error_msg)
{
	int msg_size = strlen(error_msg);
	bool single_line, break_names;

	break_names = info->key_size > 16 || msg_size > 16;
	single_line = info->key_size + msg_size <= 24 && !break_names;

	printf("key:%c", break_names ? '\n' : ' ');
	fprint_hex(stdout, key, info->key_size, " ");

	printf(single_line ? "  " : "\n");

	printf("value:%c%s", break_names ? '\n' : ' ', error_msg);

	printf("\n");
}

static void
print_entry_error(struct bpf_map_info *map_info, void *key, int lookup_errno)
{
	/* For prog_array maps or arrays of maps, failure to lookup the value
	 * means there is no entry for that key. Do not print an error message
	 * in that case.
	 */
	if ((map_is_map_of_maps(map_info->type) ||
	     map_is_map_of_progs(map_info->type)) && lookup_errno == ENOENT)
		return;

	if (json_output) {
		jsonw_start_object(json_wtr);	/* entry */
		jsonw_name(json_wtr, "key");
		print_hex_data_json(key, map_info->key_size);
		jsonw_name(json_wtr, "value");
		jsonw_start_object(json_wtr);	/* error */
		jsonw_string_field(json_wtr, "error", strerror(lookup_errno));
		jsonw_end_object(json_wtr);	/* error */
		jsonw_end_object(json_wtr);	/* entry */
	} else {
		const char *msg = NULL;

		if (lookup_errno == ENOENT)
			msg = "<no entry>";
		else if (lookup_errno == ENOSPC &&
			 map_info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY)
			msg = "<cannot read>";

		print_entry_error_msg(map_info, key,
				      msg ? : strerror(lookup_errno));
	}
}

static void print_entry_plain(struct bpf_map_info *info, unsigned char *key,
			      unsigned char *value)
{
	if (!map_is_per_cpu(info->type)) {
		bool single_line, break_names;

		break_names = info->key_size > 16 || info->value_size > 16;
		single_line = info->key_size + info->value_size <= 24 &&
			!break_names;

		if (info->key_size) {
			printf("key:%c", break_names ? '\n' : ' ');
			fprint_hex(stdout, key, info->key_size, " ");

			printf(single_line ? "  " : "\n");
		}

		if (info->value_size) {
			printf("value:%c", break_names ? '\n' : ' ');
			fprint_hex(stdout, value, info->value_size, " ");
		}

		printf("\n");
	} else {
		unsigned int i, n, step;

		n = get_possible_cpus();
		step = round_up(info->value_size, 8);

		if (info->key_size) {
			printf("key:\n");
			fprint_hex(stdout, key, info->key_size, " ");
			printf("\n");
		}
		if (info->value_size) {
			for (i = 0; i < n; i++) {
				printf("value (CPU %02d):%c",
				       i, info->value_size > 16 ? '\n' : ' ');
				fprint_hex(stdout, value + i * step,
					   info->value_size, " ");
				printf("\n");
			}
		}
	}
}

static char **parse_bytes(char **argv, const char *name, unsigned char *val,
			  unsigned int n)
{
	unsigned int i = 0, base = 0;
	char *endptr;

	if (is_prefix(*argv, "hex")) {
		base = 16;
		argv++;
	}

	while (i < n && argv[i]) {
		val[i] = strtoul(argv[i], &endptr, base);
		if (*endptr) {
			p_err("error parsing byte: %s", argv[i]);
			return NULL;
		}
		i++;
	}

	if (i != n) {
		p_err("%s expected %d bytes got %d", name, n, i);
		return NULL;
	}

	return argv + i;
}

/* on per cpu maps we must copy the provided value on all value instances */
static void fill_per_cpu_value(struct bpf_map_info *info, void *value)
{
	unsigned int i, n, step;

	if (!map_is_per_cpu(info->type))
		return;

	n = get_possible_cpus();
	step = round_up(info->value_size, 8);
	for (i = 1; i < n; i++)
		memcpy(value + i * step, value, info->value_size);
}

static int parse_elem(char **argv, struct bpf_map_info *info,
		      void *key, void *value, __u32 key_size, __u32 value_size,
		      __u32 *flags, __u32 **value_fd)
{
	if (!*argv) {
		if (!key && !value)
			return 0;
		p_err("did not find %s", key ? "key" : "value");
		return -1;
	}

	if (is_prefix(*argv, "key")) {
		if (!key) {
			if (key_size)
				p_err("duplicate key");
			else
				p_err("unnecessary key");
			return -1;
		}

		argv = parse_bytes(argv + 1, "key", key, key_size);
		if (!argv)
			return -1;

		return parse_elem(argv, info, NULL, value, key_size, value_size,
				  flags, value_fd);
	} else if (is_prefix(*argv, "value")) {
		int fd;

		if (!value) {
			if (value_size)
				p_err("duplicate value");
			else
				p_err("unnecessary value");
			return -1;
		}

		argv++;

		if (map_is_map_of_maps(info->type)) {
			int argc = 2;

			if (value_size != 4) {
				p_err("value smaller than 4B for map in map?");
				return -1;
			}
			if (!argv[0] || !argv[1]) {
				p_err("not enough value arguments for map in map");
				return -1;
			}

			fd = map_parse_fd(&argc, &argv);
			if (fd < 0)
				return -1;

			*value_fd = value;
			**value_fd = fd;
		} else if (map_is_map_of_progs(info->type)) {
			int argc = 2;

			if (value_size != 4) {
				p_err("value smaller than 4B for map of progs?");
				return -1;
			}
			if (!argv[0] || !argv[1]) {
				p_err("not enough value arguments for map of progs");
				return -1;
			}
			if (is_prefix(*argv, "id"))
				p_info("Warning: updating program array via MAP_ID, make sure this map is kept open\n"
				       "         by some process or pinned otherwise update will be lost");

			fd = prog_parse_fd(&argc, &argv);
			if (fd < 0)
				return -1;

			*value_fd = value;
			**value_fd = fd;
		} else {
			argv = parse_bytes(argv, "value", value, value_size);
			if (!argv)
				return -1;

			fill_per_cpu_value(info, value);
		}

		return parse_elem(argv, info, key, NULL, key_size, value_size,
				  flags, NULL);
	} else if (is_prefix(*argv, "any") || is_prefix(*argv, "noexist") ||
		   is_prefix(*argv, "exist")) {
		if (!flags) {
			p_err("flags specified multiple times: %s", *argv);
			return -1;
		}

		if (is_prefix(*argv, "any"))
			*flags = BPF_ANY;
		else if (is_prefix(*argv, "noexist"))
			*flags = BPF_NOEXIST;
		else if (is_prefix(*argv, "exist"))
			*flags = BPF_EXIST;

		return parse_elem(argv + 1, info, key, value, key_size,
				  value_size, NULL, value_fd);
	}

	p_err("expected key or value, got: %s", *argv);
	return -1;
}

static void show_map_header_json(struct bpf_map_info *info, json_writer_t *wtr)
{
	const char *map_type_str;

	jsonw_uint_field(wtr, "id", info->id);
	map_type_str = libbpf_bpf_map_type_str(info->type);
	if (map_type_str)
		jsonw_string_field(wtr, "type", map_type_str);
	else
		jsonw_uint_field(wtr, "type", info->type);

	if (*info->name)
		jsonw_string_field(wtr, "name", info->name);

	jsonw_name(wtr, "flags");
	jsonw_printf(wtr, "%d", info->map_flags);
}

static int show_map_close_json(int fd, struct bpf_map_info *info)
{
	char *memlock, *frozen_str;
	int frozen = 0;

	memlock = get_fdinfo(fd, "memlock");
	frozen_str = get_fdinfo(fd, "frozen");

	jsonw_start_object(json_wtr);

	show_map_header_json(info, json_wtr);

	print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);

	jsonw_uint_field(json_wtr, "bytes_key", info->key_size);
	jsonw_uint_field(json_wtr, "bytes_value", info->value_size);
	jsonw_uint_field(json_wtr, "max_entries", info->max_entries);

	if (memlock)
		jsonw_int_field(json_wtr, "bytes_memlock", atoll(memlock));
	free(memlock);

	if (info->type == BPF_MAP_TYPE_PROG_ARRAY) {
		char *owner_prog_type = get_fdinfo(fd, "owner_prog_type");
		char *owner_jited = get_fdinfo(fd, "owner_jited");

		if (owner_prog_type) {
			unsigned int prog_type = atoi(owner_prog_type);
			const char *prog_type_str;

			prog_type_str = libbpf_bpf_prog_type_str(prog_type);
			if (prog_type_str)
				jsonw_string_field(json_wtr, "owner_prog_type",
						   prog_type_str);
			else
				jsonw_uint_field(json_wtr, "owner_prog_type",
						 prog_type);
		}
		if (owner_jited)
			jsonw_bool_field(json_wtr, "owner_jited",
					 !!atoi(owner_jited));

		free(owner_prog_type);
		free(owner_jited);
	}
	close(fd);

	if (frozen_str) {
		frozen = atoi(frozen_str);
		free(frozen_str);
	}
	jsonw_int_field(json_wtr, "frozen", frozen);

	if (info->btf_id)
		jsonw_int_field(json_wtr, "btf_id", info->btf_id);

	if (!hashmap__empty(map_table)) {
		struct hashmap_entry *entry;

		jsonw_name(json_wtr, "pinned");
		jsonw_start_array(json_wtr);
		hashmap__for_each_key_entry(map_table, entry, info->id)
			jsonw_string(json_wtr, entry->pvalue);
		jsonw_end_array(json_wtr);
	}

	emit_obj_refs_json(refs_table, info->id, json_wtr);

	jsonw_end_object(json_wtr);

	return 0;
}

static void show_map_header_plain(struct bpf_map_info *info)
{
	const char *map_type_str;

	printf("%u: ", info->id);

	map_type_str = libbpf_bpf_map_type_str(info->type);
	if (map_type_str)
		printf("%s  ", map_type_str);
	else
		printf("type %u  ", info->type);

	if (*info->name)
		printf("name %s  ", info->name);

	printf("flags 0x%x", info->map_flags);
	print_dev_plain(info->ifindex, info->netns_dev, info->netns_ino);
	printf("\n");
}

static int show_map_close_plain(int fd, struct bpf_map_info *info)
{
	char *memlock, *frozen_str;
	int frozen = 0;

	memlock = get_fdinfo(fd, "memlock");
	frozen_str = get_fdinfo(fd, "frozen");

	show_map_header_plain(info);
	printf("\tkey %uB  value %uB  max_entries %u",
	       info->key_size, info->value_size, info->max_entries);

	if (memlock)
		printf("  memlock %sB", memlock);
	free(memlock);

	if (info->type == BPF_MAP_TYPE_PROG_ARRAY) {
		char *owner_prog_type = get_fdinfo(fd, "owner_prog_type");
		char *owner_jited = get_fdinfo(fd, "owner_jited");

		if (owner_prog_type || owner_jited)
			printf("\n\t");
		if (owner_prog_type) {
			unsigned int prog_type = atoi(owner_prog_type);
			const char *prog_type_str;

			prog_type_str = libbpf_bpf_prog_type_str(prog_type);
			if (prog_type_str)
				printf("owner_prog_type %s  ", prog_type_str);
			else
				printf("owner_prog_type %d  ", prog_type);
		}
		if (owner_jited)
			printf("owner%s jited",
			       atoi(owner_jited) ? "" : " not");

		free(owner_prog_type);
		free(owner_jited);
	}
	close(fd);

	if (!hashmap__empty(map_table)) {
		struct hashmap_entry *entry;

		hashmap__for_each_key_entry(map_table, entry, info->id)
			printf("\n\tpinned %s", (char *)entry->pvalue);
	}

	if (frozen_str) {
		frozen = atoi(frozen_str);
		free(frozen_str);
	}

	if (info->btf_id || frozen)
		printf("\n\t");

	if (info->btf_id)
		printf("btf_id %d", info->btf_id);

	if (frozen)
		printf("%sfrozen", info->btf_id ? "  " : "");

	emit_obj_refs_plain(refs_table, info->id, "\n\tpids ");

	printf("\n");
	return 0;
}

static int do_show_subset(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	int *fds = NULL;
	int nb_fds, i;
	int err = -1;

	fds = malloc(sizeof(int));
	if (!fds) {
		p_err("mem alloc failed");
		return -1;
	}
	nb_fds = map_parse_fds(&argc, &argv, &fds);
	if (nb_fds < 1)
		goto exit_free;

	if (json_output && nb_fds > 1)
		jsonw_start_array(json_wtr);	/* root array */
	for (i = 0; i < nb_fds; i++) {
		err = bpf_obj_get_info_by_fd(fds[i], &info, &len);
		if (err) {
			p_err("can't get map info: %s",
			      strerror(errno));
			for (; i < nb_fds; i++)
				close(fds[i]);
			break;
		}

		if (json_output)
			show_map_close_json(fds[i], &info);
		else
			show_map_close_plain(fds[i], &info);

		close(fds[i]);
	}
	if (json_output && nb_fds > 1)
		jsonw_end_array(json_wtr);	/* root array */

exit_free:
	free(fds);
	return err;
}

static int do_show(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	__u32 id = 0;
	int err;
	int fd;

	if (show_pinned) {
		map_table = hashmap__new(hash_fn_for_key_as_id,
					 equal_fn_for_key_as_id, NULL);
		if (IS_ERR(map_table)) {
			p_err("failed to create hashmap for pinned paths");
			return -1;
		}
		build_pinned_obj_table(map_table, BPF_OBJ_MAP);
	}
	build_obj_refs_table(&refs_table, BPF_OBJ_MAP);

	if (argc == 2)
		return do_show_subset(argc, argv);

	if (argc)
		return BAD_ARG();

	if (json_output)
		jsonw_start_array(json_wtr);
	while (true) {
		err = bpf_map_get_next_id(id, &id);
		if (err) {
			if (errno == ENOENT)
				break;
			p_err("can't get next map: %s%s", strerror(errno),
			      errno == EINVAL ? " -- kernel too old?" : "");
			break;
		}

		fd = bpf_map_get_fd_by_id(id);
		if (fd < 0) {
			if (errno == ENOENT)
				continue;
			p_err("can't get map by id (%u): %s",
			      id, strerror(errno));
			break;
		}

		err = bpf_obj_get_info_by_fd(fd, &info, &len);
		if (err) {
			p_err("can't get map info: %s", strerror(errno));
			close(fd);
			break;
		}

		if (json_output)
			show_map_close_json(fd, &info);
		else
			show_map_close_plain(fd, &info);
	}
	if (json_output)
		jsonw_end_array(json_wtr);

	delete_obj_refs_table(refs_table);

	if (show_pinned)
		delete_pinned_obj_table(map_table);

	return errno == ENOENT ? 0 : -1;
}

static int dump_map_elem(int fd, void *key, void *value,
			 struct bpf_map_info *map_info, struct btf *btf,
			 json_writer_t *btf_wtr)
{
	if (bpf_map_lookup_elem(fd, key, value)) {
		print_entry_error(map_info, key, errno);
		return -1;
	}

	if (json_output) {
		print_entry_json(map_info, key, value, btf);
	} else if (btf) {
		struct btf_dumper d = {
			.btf = btf,
			.jw = btf_wtr,
			.is_plain_text = true,
		};

		do_dump_btf(&d, map_info, key, value);
	} else {
		print_entry_plain(map_info, key, value);
	}

	return 0;
}

static int maps_have_btf(int *fds, int nb_fds)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	int err, i;

	for (i = 0; i < nb_fds; i++) {
		err = bpf_obj_get_info_by_fd(fds[i], &info, &len);
		if (err) {
			p_err("can't get map info: %s", strerror(errno));
			return -1;
		}

		if (!info.btf_id)
			return 0;
	}

	return 1;
}

static struct btf *btf_vmlinux;

static int get_map_kv_btf(const struct bpf_map_info *info, struct btf **btf)
{
	int err = 0;

	if (info->btf_vmlinux_value_type_id) {
		if (!btf_vmlinux) {
			btf_vmlinux = libbpf_find_kernel_btf();
			if (!btf_vmlinux) {
				p_err("failed to get kernel btf");
				return -errno;
			}
		}
		*btf = btf_vmlinux;
	} else if (info->btf_value_type_id) {
		*btf = btf__load_from_kernel_by_id(info->btf_id);
		if (!*btf) {
			err = -errno;
			p_err("failed to get btf");
		}
	} else {
		*btf = NULL;
	}

	return err;
}

static void free_map_kv_btf(struct btf *btf)
{
	if (btf != btf_vmlinux)
		btf__free(btf);
}

static int
map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
	 bool show_header)
{
	void *key, *value, *prev_key;
	unsigned int num_elems = 0;
	struct btf *btf = NULL;
	int err;

	key = malloc(info->key_size);
	value = alloc_value(info);
	if (!key || !value) {
		p_err("mem alloc failed");
		err = -1;
		goto exit_free;
	}

	prev_key = NULL;

	if (wtr) {
		err = get_map_kv_btf(info, &btf);
		if (err) {
			goto exit_free;
		}

		if (show_header) {
			jsonw_start_object(wtr);	/* map object */
			show_map_header_json(info, wtr);
			jsonw_name(wtr, "elements");
		}
		jsonw_start_array(wtr);		/* elements */
	} else if (show_header) {
		show_map_header_plain(info);
	}

	if (info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY &&
	    info->value_size != 8) {
		const char *map_type_str;

		map_type_str = libbpf_bpf_map_type_str(info->type);
		p_info("Warning: cannot read values from %s map with value_size != 8",
		       map_type_str);
	}
	while (true) {
		err = bpf_map_get_next_key(fd, prev_key, key);
		if (err) {
			if (errno == ENOENT)
				err = 0;
			break;
		}
		if (!dump_map_elem(fd, key, value, info, btf, wtr))
			num_elems++;
		prev_key = key;
	}

	if (wtr) {
		jsonw_end_array(wtr);	/* elements */
		if (show_header)
			jsonw_end_object(wtr);	/* map object */
	} else {
		printf("Found %u element%s\n", num_elems,
		       num_elems != 1 ? "s" : "");
	}

exit_free:
	free(key);
	free(value);
	close(fd);
	free_map_kv_btf(btf);

	return err;
}

static int do_dump(int argc, char **argv)
{
	json_writer_t *wtr = NULL, *btf_wtr = NULL;
	struct bpf_map_info info = {};
	int nb_fds, i = 0;
	__u32 len = sizeof(info);
	int *fds = NULL;
	int err = -1;

	if (argc != 2)
		usage();

	fds = malloc(sizeof(int));
	if (!fds) {
		p_err("mem alloc failed");
		return -1;
	}
	nb_fds = map_parse_fds(&argc, &argv, &fds);
	if (nb_fds < 1)
		goto exit_free;

	if (json_output) {
		wtr = json_wtr;
	} else {
		int do_plain_btf;

		do_plain_btf = maps_have_btf(fds, nb_fds);
		if (do_plain_btf < 0)
			goto exit_close;

		if (do_plain_btf) {
			btf_wtr = get_btf_writer();
			wtr = btf_wtr;
			if (!btf_wtr)
				p_info("failed to create json writer for btf. falling back to plain output");
		}
	}

	if (wtr && nb_fds > 1)
		jsonw_start_array(wtr);	/* root array */
	for (i = 0; i < nb_fds; i++) {
		if (bpf_obj_get_info_by_fd(fds[i], &info, &len)) {
			p_err("can't get map info: %s", strerror(errno));
			break;
		}
		err = map_dump(fds[i], &info, wtr, nb_fds > 1);
		if (!wtr && i != nb_fds - 1)
			printf("\n");

		if (err)
			break;
		close(fds[i]);
	}
	if (wtr && nb_fds > 1)
		jsonw_end_array(wtr);	/* root array */

	if (btf_wtr)
		jsonw_destroy(&btf_wtr);
exit_close:
	for (; i < nb_fds; i++)
		close(fds[i]);
exit_free:
	free(fds);
	btf__free(btf_vmlinux);
	return err;
}

static int alloc_key_value(struct bpf_map_info *info, void **key, void **value)
{
	*key = NULL;
	*value = NULL;

	if (info->key_size) {
		*key = malloc(info->key_size);
		if (!*key) {
			p_err("key mem alloc failed");
			return -1;
		}
	}

	if (info->value_size) {
		*value = alloc_value(info);
		if (!*value) {
			p_err("value mem alloc failed");
			free(*key);
			*key = NULL;
			return -1;
		}
	}

	return 0;
}

static int do_update(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	__u32 *value_fd = NULL;
	__u32 flags = BPF_ANY;
	void *key, *value;
	int fd, err;

	if (argc < 2)
		usage();

	fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
	if (fd < 0)
		return -1;

	err = alloc_key_value(&info, &key, &value);
	if (err)
		goto exit_free;

	err = parse_elem(argv, &info, key, value, info.key_size,
			 info.value_size, &flags, &value_fd);
	if (err)
		goto exit_free;

	err = bpf_map_update_elem(fd, key, value, flags);
	if (err) {
		p_err("update failed: %s", strerror(errno));
		goto exit_free;
	}

exit_free:
	if (value_fd)
		close(*value_fd);
	free(key);
	free(value);
	close(fd);

	if (!err && json_output)
		jsonw_null(json_wtr);
	return err;
}

static void print_key_value(struct bpf_map_info *info, void *key,
			    void *value)
{
	json_writer_t *btf_wtr;
	struct btf *btf;

	if (get_map_kv_btf(info, &btf))
		return;

	if (json_output) {
		print_entry_json(info, key, value, btf);
	} else if (btf) {
		/* if here json_wtr wouldn't have been initialised,
		 * so let's create separate writer for btf
		 */
		btf_wtr = get_btf_writer();
		if (!btf_wtr) {
			p_info("failed to create json writer for btf. falling back to plain output");
			btf__free(btf);
			btf = NULL;
			print_entry_plain(info, key, value);
		} else {
			struct btf_dumper d = {
				.btf = btf,
				.jw = btf_wtr,
				.is_plain_text = true,
			};

			do_dump_btf(&d, info, key, value);
			jsonw_destroy(&btf_wtr);
		}
	} else {
		print_entry_plain(info, key, value);
	}
	btf__free(btf);
}

static int do_lookup(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	void *key, *value;
	int err;
	int fd;

	if (argc < 2)
		usage();

	fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
	if (fd < 0)
		return -1;

	err = alloc_key_value(&info, &key, &value);
	if (err)
		goto exit_free;

	err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
	if (err)
		goto exit_free;

	err = bpf_map_lookup_elem(fd, key, value);
	if (err) {
		if (errno == ENOENT) {
			if (json_output) {
				jsonw_null(json_wtr);
			} else {
				printf("key:\n");
				fprint_hex(stdout, key, info.key_size, " ");
				printf("\n\nNot found\n");
			}
		} else {
			p_err("lookup failed: %s", strerror(errno));
		}

		goto exit_free;
	}

	/* here means bpf_map_lookup_elem() succeeded */
	print_key_value(&info, key, value);

exit_free:
	free(key);
	free(value);
	close(fd);

	return err;
}

static int do_getnext(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	void *key, *nextkey;
	int err;
	int fd;

	if (argc < 2)
		usage();

	fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
	if (fd < 0)
		return -1;

	key = malloc(info.key_size);
	nextkey = malloc(info.key_size);
	if (!key || !nextkey) {
		p_err("mem alloc failed");
		err = -1;
		goto exit_free;
	}

	if (argc) {
		err = parse_elem(argv, &info, key, NULL, info.key_size, 0,
				 NULL, NULL);
		if (err)
			goto exit_free;
	} else {
		free(key);
		key = NULL;
	}

	err = bpf_map_get_next_key(fd, key, nextkey);
	if (err) {
		p_err("can't get next key: %s", strerror(errno));
		goto exit_free;
	}

	if (json_output) {
		jsonw_start_object(json_wtr);
		if (key) {
			jsonw_name(json_wtr, "key");
			print_hex_data_json(key, info.key_size);
		} else {
			jsonw_null_field(json_wtr, "key");
		}
		jsonw_name(json_wtr, "next_key");
		print_hex_data_json(nextkey, info.key_size);
		jsonw_end_object(json_wtr);
	} else {
		if (key) {
			printf("key:\n");
			fprint_hex(stdout, key, info.key_size, " ");
			printf("\n");
		} else {
			printf("key: None\n");
		}
		printf("next key:\n");
		fprint_hex(stdout, nextkey, info.key_size, " ");
		printf("\n");
	}

exit_free:
	free(nextkey);
	free(key);
	close(fd);

	return err;
}

static int do_delete(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	void *key;
	int err;
	int fd;

	if (argc < 2)
		usage();

	fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
	if (fd < 0)
		return -1;

	key = malloc(info.key_size);
	if (!key) {
		p_err("mem alloc failed");
		err = -1;
		goto exit_free;
	}

	err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
	if (err)
		goto exit_free;

	err = bpf_map_delete_elem(fd, key);
	if (err)
		p_err("delete failed: %s", strerror(errno));

exit_free:
	free(key);
	close(fd);

	if (!err && json_output)
		jsonw_null(json_wtr);
	return err;
}

static int do_pin(int argc, char **argv)
{
	int err;

	err = do_pin_any(argc, argv, map_parse_fd);
	if (!err && json_output)
		jsonw_null(json_wtr);
	return err;
}

static int do_create(int argc, char **argv)
{
	LIBBPF_OPTS(bpf_map_create_opts, attr);
	enum bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC;
	__u32 key_size = 0, value_size = 0, max_entries = 0;
	const char *map_name = NULL;
	const char *pinfile;
	int err = -1, fd;

	if (!REQ_ARGS(7))
		return -1;
	pinfile = GET_ARG();

	while (argc) {
		if (!REQ_ARGS(2))
			return -1;

		if (is_prefix(*argv, "type")) {
			NEXT_ARG();

			if (map_type) {
				p_err("map type already specified");
				goto exit;
			}

			map_type = map_type_from_str(*argv);
			if ((int)map_type < 0) {
				p_err("unrecognized map type: %s", *argv);
				goto exit;
			}
			NEXT_ARG();
		} else if (is_prefix(*argv, "name")) {
			NEXT_ARG();
			map_name = GET_ARG();
		} else if (is_prefix(*argv, "key")) {
			if (parse_u32_arg(&argc, &argv, &key_size,
					  "key size"))
				goto exit;
		} else if (is_prefix(*argv, "value")) {
			if (parse_u32_arg(&argc, &argv, &value_size,
					  "value size"))
				goto exit;
		} else if (is_prefix(*argv, "entries")) {
			if (parse_u32_arg(&argc, &argv, &max_entries,
					  "max entries"))
				goto exit;
		} else if (is_prefix(*argv, "flags")) {
			if (parse_u32_arg(&argc, &argv, &attr.map_flags,
					  "flags"))
				goto exit;
		} else if (is_prefix(*argv, "dev")) {
			NEXT_ARG();

			if (attr.map_ifindex) {
				p_err("offload device already specified");
				goto exit;
			}

			attr.map_ifindex = if_nametoindex(*argv);
			if (!attr.map_ifindex) {
				p_err("unrecognized netdevice '%s': %s",
				      *argv, strerror(errno));
				goto exit;
			}
			NEXT_ARG();
		} else if (is_prefix(*argv, "inner_map")) {
			struct bpf_map_info info = {};
			__u32 len = sizeof(info);
			int inner_map_fd;

			NEXT_ARG();
			if (!REQ_ARGS(2))
				usage();
			inner_map_fd = map_parse_fd_and_info(&argc, &argv,
							     &info, &len);
			if (inner_map_fd < 0)
				return -1;
			attr.inner_map_fd = inner_map_fd;
		} else {
			p_err("unknown arg %s", *argv);
			goto exit;
		}
	}

	if (!map_name) {
		p_err("map name not specified");
		goto exit;
	}

	set_max_rlimit();

	fd = bpf_map_create(map_type, map_name, key_size, value_size, max_entries, &attr);
	if (fd < 0) {
		p_err("map create failed: %s", strerror(errno));
		goto exit;
	}

	err = do_pin_fd(fd, pinfile);
	close(fd);
	if (err)
		goto exit;

	if (json_output)
		jsonw_null(json_wtr);

exit:
	if (attr.inner_map_fd > 0)
		close(attr.inner_map_fd);

	return err;
}

static int do_pop_dequeue(int argc, char **argv)
{
	struct bpf_map_info info = {};
	__u32 len = sizeof(info);
	void *key, *value;
	int err;
	int fd;

	if (argc < 2)
		usage();

	fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
	if (fd < 0)
		return -1;

	err = alloc_key_value(&info, &key, &value);
	if (err)
		goto exit_free;

	err = bpf_map_lookup_and_delete_elem(fd, key, value);
	if (err) {
		if (errno == ENOENT) {
			if (json_output)
				jsonw_null(json_wtr);
			else
				printf("Error: empty map\n");
		} else {
			p_err("pop failed: %s", strerror(errno));
		}

		goto exit_free;
	}

	print_key_value(&info, key, value);

exit_free:
	free(key);
	free(value);
	close(fd);

	return err;
}

static int do_freeze(int argc, char **argv)
{
	int err, fd;

	if (!REQ_ARGS(2))
		return -1;

	fd = map_parse_fd(&argc, &argv);
	if (fd < 0)
		return -1;

	if (argc) {
		close(fd);
		return BAD_ARG();
	}

	err = bpf_map_freeze(fd);
	close(fd);
	if (err) {
		p_err("failed to freeze map: %s", strerror(errno));
		return err;
	}

	if (json_output)
		jsonw_null(json_wtr);

	return 0;
}

static int do_help(int argc, char **argv)
{
	if (json_output) {
		jsonw_null(json_wtr);
		return 0;
	}

	fprintf(stderr,
		"Usage: %1$s %2$s { show | list }   [MAP]\n"
		"       %1$s %2$s create     FILE type TYPE key KEY_SIZE value VALUE_SIZE \\\n"
		"                                  entries MAX_ENTRIES name NAME [flags FLAGS] \\\n"
		"                                  [inner_map MAP] [dev NAME]\n"
		"       %1$s %2$s dump       MAP\n"
		"       %1$s %2$s update     MAP [key DATA] [value VALUE] [UPDATE_FLAGS]\n"
		"       %1$s %2$s lookup     MAP [key DATA]\n"
		"       %1$s %2$s getnext    MAP [key DATA]\n"
		"       %1$s %2$s delete     MAP  key DATA\n"
		"       %1$s %2$s pin        MAP  FILE\n"
		"       %1$s %2$s event_pipe MAP [cpu N index M]\n"
		"       %1$s %2$s peek       MAP\n"
		"       %1$s %2$s push       MAP value VALUE\n"
		"       %1$s %2$s pop        MAP\n"
		"       %1$s %2$s enqueue    MAP value VALUE\n"
		"       %1$s %2$s dequeue    MAP\n"
		"       %1$s %2$s freeze     MAP\n"
		"       %1$s %2$s help\n"
		"\n"
		"       " HELP_SPEC_MAP "\n"
		"       DATA := { [hex] BYTES }\n"
		"       " HELP_SPEC_PROGRAM "\n"
		"       VALUE := { DATA | MAP | PROG }\n"
		"       UPDATE_FLAGS := { any | exist | noexist }\n"
		"       TYPE := { hash | array | prog_array | perf_event_array | percpu_hash |\n"
		"                 percpu_array | stack_trace | cgroup_array | lru_hash |\n"
		"                 lru_percpu_hash | lpm_trie | array_of_maps | hash_of_maps |\n"
		"                 devmap | devmap_hash | sockmap | cpumap | xskmap | sockhash |\n"
		"                 cgroup_storage | reuseport_sockarray | percpu_cgroup_storage |\n"
		"                 queue | stack | sk_storage | struct_ops | ringbuf | inode_storage |\n"
		"                 task_storage | bloom_filter | user_ringbuf | cgrp_storage }\n"
		"       " HELP_SPEC_OPTIONS " |\n"
		"                    {-f|--bpffs} | {-n|--nomount} }\n"
		"",
		bin_name, argv[-2]);

	return 0;
}

static const struct cmd cmds[] = {
	{ "show",	do_show },
	{ "list",	do_show },
	{ "help",	do_help },
	{ "dump",	do_dump },
	{ "update",	do_update },
	{ "lookup",	do_lookup },
	{ "getnext",	do_getnext },
	{ "delete",	do_delete },
	{ "pin",	do_pin },
	{ "event_pipe",	do_event_pipe },
	{ "create",	do_create },
	{ "peek",	do_lookup },
	{ "push",	do_update },
	{ "enqueue",	do_update },
	{ "pop",	do_pop_dequeue },
	{ "dequeue",	do_pop_dequeue },
	{ "freeze",	do_freeze },
	{ 0 }
};

int do_map(int argc, char **argv)
{
	return cmd_select(cmds, argc, argv, do_help);
}
