// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * utils.c	RDMA tool
 * Authors:     Leon Romanovsky <leonro@mellanox.com>
 */

#include "rdma.h"
#include <ctype.h>
#include <inttypes.h>

int rd_argc(struct rd *rd)
{
	return rd->argc;
}

char *rd_argv(struct rd *rd)
{
	if (!rd_argc(rd))
		return NULL;
	return *rd->argv;
}

int strcmpx(const char *str1, const char *str2)
{
	if (strlen(str1) > strlen(str2))
		return -1;
	return strncmp(str1, str2, strlen(str1));
}

static bool rd_argv_match(struct rd *rd, const char *pattern)
{
	if (!rd_argc(rd))
		return false;
	return strcmpx(rd_argv(rd), pattern) == 0;
}

void rd_arg_inc(struct rd *rd)
{
	if (!rd_argc(rd))
		return;
	rd->argc--;
	rd->argv++;
}

bool rd_no_arg(struct rd *rd)
{
	return rd_argc(rd) == 0;
}

/*
 * Possible input:output
 * dev/port    | first port | is_dump_all
 * mlx5_1      | 0          | true
 * mlx5_1/     | 0          | true
 * mlx5_1/0    | 0          | false
 * mlx5_1/1    | 1          | false
 * mlx5_1/-    | 0          | false
 *
 * In strict port mode, a non-0 port must be provided
 */
static int get_port_from_argv(struct rd *rd, uint32_t *port,
			      bool *is_dump_all, bool strict_port)
{
	char *slash;

	*port = 0;
	*is_dump_all = strict_port ? false : true;

	slash = strchr(rd_argv(rd), '/');
	/* if no port found, return 0 */
	if (slash++) {
		if (*slash == '-') {
			if (strict_port)
				return -EINVAL;
			*is_dump_all = false;
			return 0;
		}

		if (isdigit(*slash)) {
			*is_dump_all = false;
			*port = atoi(slash);
		}
		if (!*port && strlen(slash))
			return -EINVAL;
	}
	if (strict_port && (*port == 0))
		return -EINVAL;

	return 0;
}

static struct dev_map *dev_map_alloc(const char *dev_name)
{
	struct dev_map *dev_map;

	dev_map = calloc(1, sizeof(*dev_map));
	if (!dev_map)
		return NULL;
	dev_map->dev_name = strdup(dev_name);
	if (!dev_map->dev_name) {
		free(dev_map);
		return NULL;
	}

	return dev_map;
}

static void dev_map_cleanup(struct rd *rd)
{
	struct dev_map *dev_map, *tmp;

	list_for_each_entry_safe(dev_map, tmp,
				 &rd->dev_map_list, list) {
		list_del(&dev_map->list);
		free(dev_map->dev_name);
		free(dev_map);
	}
}

static int add_filter(struct rd *rd, char *key, char *value,
		      const struct filters valid_filters[])
{
	char cset[] = "1234567890,-";
	struct filter_entry *fe;
	bool key_found = false;
	int idx = 0;
	char *endp;
	int ret;

	fe = calloc(1, sizeof(*fe));
	if (!fe)
		return -ENOMEM;

	while (idx < MAX_NUMBER_OF_FILTERS && valid_filters[idx].name) {
		if (!strcmpx(key, valid_filters[idx].name)) {
			key_found = true;
			break;
		}
		idx++;
	}
	if (!key_found) {
		pr_err("Unsupported filter option: %s\n", key);
		ret = -EINVAL;
		goto err;
	}

	/*
	 * Check the filter validity, not optimal, but works
	 *
	 * Actually, there are three types of filters
	 *  numeric - for example PID or QPN
	 *  string  - for example states
	 *  link    - user requested to filter on specific link
	 *            e.g. mlx5_1/1, mlx5_1/-, mlx5_1 ...
	 */
	if (valid_filters[idx].is_number &&
	    strspn(value, cset) != strlen(value)) {
		pr_err("%s filter accepts \"%s\" characters only\n", key, cset);
		ret = -EINVAL;
		goto err;
	}

	fe->key = strdup(key);
	fe->value = strdup(value);
	if (!fe->key || !fe->value) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	errno = 0;
	strtol(fe->value, &endp, 10);
	if (valid_filters[idx].is_doit && !errno && *endp == '\0')
		fe->is_doit = true;

	for (idx = 0; idx < strlen(fe->value); idx++)
		fe->value[idx] = tolower(fe->value[idx]);

	list_add_tail(&fe->list, &rd->filter_list);
	return 0;

err_alloc:
	free(fe->value);
	free(fe->key);
err:
	free(fe);
	return ret;
}

bool rd_doit_index(struct rd *rd, uint32_t *idx)
{
	struct filter_entry *fe;

	list_for_each_entry(fe, &rd->filter_list, list) {
		if (fe->is_doit) {
			*idx = atoi(fe->value);
			return true;
		}
	}

	return false;
}

int rd_build_filter(struct rd *rd, const struct filters valid_filters[])
{
	int ret = 0;
	int idx = 0;

	if (!valid_filters || !rd_argc(rd))
		goto out;

	if (rd_argc(rd) == 1) {
		pr_err("No filter data was supplied to filter option %s\n", rd_argv(rd));
		ret = -EINVAL;
		goto out;
	}

	if (rd_argc(rd) % 2) {
		pr_err("There is filter option without data\n");
		ret = -EINVAL;
		goto out;
	}

	while (idx != rd_argc(rd)) {
		/*
		 * We can do micro-optimization and skip "dev"
		 * and "link" filters, but it is not worth of it.
		 */
		ret = add_filter(rd, *(rd->argv + idx),
				 *(rd->argv + idx + 1), valid_filters);
		if (ret)
			goto out;
		idx += 2;
	}

out:
	return ret;
}

static bool rd_check_is_key_exist(struct rd *rd, const char *key)
{
	struct filter_entry *fe;

	list_for_each_entry(fe, &rd->filter_list, list) {
		if (!strcmpx(fe->key, key))
			return true;
	}

	return false;
}

/*
 * Check if string entry is filtered:
 *  * key doesn't exist -> user didn't request -> not filtered
 */
static bool rd_check_is_string_filtered(struct rd *rd, const char *key,
					const char *val)
{
	bool key_is_filtered = false;
	struct filter_entry *fe;
	char *p = NULL;
	char *str;

	list_for_each_entry(fe, &rd->filter_list, list) {
		if (!strcmpx(fe->key, key)) {
			/* We found the key */
			p = strdup(fe->value);
			key_is_filtered = true;
			if (!p) {
				/*
				 * Something extremely wrong if we fail
				 * to allocate small amount of bytes.
				 */
				pr_err("Found key, but failed to allocate memory to store value\n");
				return key_is_filtered;
			}

			/*
			 * Need to check if value in range
			 * It can come in the following formats
			 * and their permutations:
			 * str
			 * str1,str2
			 */
			str = strtok(p, ",");
			while (str) {
				if (strlen(str) == strlen(val) &&
				    !strcasecmp(str, val)) {
					key_is_filtered = false;
					goto out;
				}
				str = strtok(NULL, ",");
			}
			goto out;
		}
	}

out:
	free(p);
	return key_is_filtered;
}

/*
 * Check if key is filtered:
 * key doesn't exist -> user didn't request -> not filtered
 */
static bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val)
{
	bool key_is_filtered = false;
	struct filter_entry *fe;

	list_for_each_entry(fe, &rd->filter_list, list) {
		uint32_t left_val = 0, fe_value = 0;
		bool range_check = false;
		char *p = fe->value;

		if (!strcmpx(fe->key, key)) {
			/* We found the key */
			key_is_filtered = true;
			/*
			 * Need to check if value in range
			 * It can come in the following formats
			 * (and their permutations):
			 * numb
			 * numb1,numb2
			 * ,numb1,numb2
			 * numb1-numb2
			 * numb1,numb2-numb3,numb4-numb5
			 */
			while (*p) {
				if (isdigit(*p)) {
					fe_value = strtol(p, &p, 10);
					if (fe_value == val ||
					    (range_check && left_val < val &&
					     val < fe_value)) {
						key_is_filtered = false;
						goto out;
					}
					range_check = false;
				} else {
					if (*p == '-') {
						left_val = fe_value;
						range_check = true;
					}
					p++;
				}
			}
			goto out;
		}
	}

out:
	return key_is_filtered;
}

bool rd_is_filtered_attr(struct rd *rd, const char *key, uint32_t val,
			 struct nlattr *attr)
{
	if (!attr)
		return rd_check_is_key_exist(rd, key);

	return rd_check_is_filtered(rd, key, val);
}

bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val,
				struct nlattr *attr)
{
	if (!attr)
		rd_check_is_key_exist(rd, key);

	return rd_check_is_string_filtered(rd, key, val);
}

static void filters_cleanup(struct rd *rd)
{
	struct filter_entry *fe, *tmp;

	list_for_each_entry_safe(fe, tmp,
				 &rd->filter_list, list) {
		list_del(&fe->list);
		free(fe->key);
		free(fe->value);
		free(fe);
	}
}

static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
	[RDMA_NLDEV_ATTR_DEV_INDEX] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_CAP_FLAGS] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_FW_VERSION] = MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_NODE_GUID] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_LID] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_SM_LID] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_LMC] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_PORT_STATE] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_RES_SUMMARY]	= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY]	= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_RES_QP]		= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_QP_ENTRY]		= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_LQPN]	= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_RQPN]	= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_RQ_PSN]		= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_SQ_PSN]		= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]	= MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_RES_TYPE]		= MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_RES_STATE]		= MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_RES_PID]		= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_KERN_NAME]	= MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_RES_CM_ID]		= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_CM_ID_ENTRY]	= MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_PS]		= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_SRC_ADDR]		= MNL_TYPE_UNSPEC,
	[RDMA_NLDEV_ATTR_RES_DST_ADDR]		= MNL_TYPE_UNSPEC,
	[RDMA_NLDEV_ATTR_RES_CQ] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_CQ_ENTRY] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_CQE] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_USECNT] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_RES_POLL_CTX] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_RES_MR] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_MR_ENTRY] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_RES_RKEY] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_LKEY] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_RES_IOVA] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_RES_MRLEN] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_NDEV_INDEX]		= MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_NDEV_NAME]		= MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_DRIVER] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_DRIVER_ENTRY] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_DRIVER_STRING] = MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_DRIVER_S32] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_DRIVER_U32] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_DRIVER_S64] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_DRIVER_U64] = MNL_TYPE_U64,
	[RDMA_NLDEV_SYS_ATTR_NETNS_MODE] = MNL_TYPE_U8,
	[RDMA_NLDEV_ATTR_STAT_COUNTER] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_STAT_COUNTER_ENTRY] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_STAT_COUNTER_ID] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_STAT_HWCOUNTERS] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY] = MNL_TYPE_NESTED,
	[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_NAME] = MNL_TYPE_NUL_STRING,
	[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_VALUE] = MNL_TYPE_U64,
	[RDMA_NLDEV_ATTR_STAT_MODE] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_STAT_RES] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK] = MNL_TYPE_U32,
	[RDMA_NLDEV_ATTR_DEV_DIM] = MNL_TYPE_U8,
};

int rd_attr_check(const struct nlattr *attr, int *typep)
{
	int type;

	if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX) < 0)
		return MNL_CB_ERROR;

	type = mnl_attr_get_type(attr);

	if (mnl_attr_validate(attr, nldev_policy[type]) < 0)
		return MNL_CB_ERROR;

	*typep = nldev_policy[type];
	return MNL_CB_OK;
}

int rd_attr_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type;

	if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX - 1) < 0)
		/* We received unknown attribute */
		return MNL_CB_OK;

	type = mnl_attr_get_type(attr);

	if (mnl_attr_validate(attr, nldev_policy[type]) < 0)
		return MNL_CB_ERROR;

	tb[type] = attr;
	return MNL_CB_OK;
}

int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
	struct dev_map *dev_map;
	struct rd *rd = data;
	const char *dev_name;

	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
	if (!tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
		return MNL_CB_ERROR;
	if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
		pr_err("This tool doesn't support switches yet\n");
		return MNL_CB_ERROR;
	}

	dev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);

	dev_map = dev_map_alloc(dev_name);
	if (!dev_map)
		/* The main function will cleanup the allocations */
		return MNL_CB_ERROR;
	list_add_tail(&dev_map->list, &rd->dev_map_list);

	dev_map->num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
	dev_map->idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
	return MNL_CB_OK;
}

void rd_free(struct rd *rd)
{
	if (!rd)
		return;
	free(rd->buff);
	dev_map_cleanup(rd);
	filters_cleanup(rd);
}

int rd_set_arg_to_devname(struct rd *rd)
{
	int ret = 0;

	while (!rd_no_arg(rd)) {
		if (rd_argv_match(rd, "dev") || rd_argv_match(rd, "link")) {
			rd_arg_inc(rd);
			if (rd_no_arg(rd)) {
				pr_err("No device name was supplied\n");
				ret = -EINVAL;
			}
			goto out;
		}
		rd_arg_inc(rd);
	}
out:
	return ret;
}

int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port)
{
	struct dev_map *dev_map;
	uint32_t port;
	int ret = 0;

	if (rd->json_output)
		jsonw_start_array(rd->jw);
	if (rd_no_arg(rd)) {
		list_for_each_entry(dev_map, &rd->dev_map_list, list) {
			rd->dev_idx = dev_map->idx;
			port = (strict_port) ? 1 : 0;
			for (; port < dev_map->num_ports + 1; port++) {
				rd->port_idx = port;
				ret = cb(rd);
				if (ret)
					goto out;
			}
		}

	} else {
		bool is_dump_all;

		dev_map = dev_map_lookup(rd, true);
		ret = get_port_from_argv(rd, &port, &is_dump_all, strict_port);
		if (!dev_map || port > dev_map->num_ports || (!port && ret)) {
			pr_err("Wrong device name\n");
			ret = -ENOENT;
			goto out;
		}
		rd_arg_inc(rd);
		rd->dev_idx = dev_map->idx;
		rd->port_idx = port;
		for (; rd->port_idx < dev_map->num_ports + 1; rd->port_idx++) {
			ret = cb(rd);
			if (ret)
				goto out;
			if (!is_dump_all)
				/*
				 * We got request to show link for devname
				 * with port index.
				 */
				break;
		}
	}

out:
	if (rd->json_output)
		jsonw_end_array(rd->jw);
	return ret;
}

int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd))
{
	struct dev_map *dev_map;
	int ret = 0;

	if (rd->json_output)
		jsonw_start_array(rd->jw);
	if (rd_no_arg(rd)) {
		list_for_each_entry(dev_map, &rd->dev_map_list, list) {
			rd->dev_idx = dev_map->idx;
			ret = cb(rd);
			if (ret)
				goto out;
		}
	} else {
		dev_map = dev_map_lookup(rd, false);
		if (!dev_map) {
			pr_err("Wrong device name - %s\n", rd_argv(rd));
			ret = -ENOENT;
			goto out;
		}
		rd_arg_inc(rd);
		rd->dev_idx = dev_map->idx;
		ret = cb(rd);
	}
out:
	if (rd->json_output)
		jsonw_end_array(rd->jw);
	return ret;
}

int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd))
{
	if (rd_no_arg(rd)) {
		pr_err("Please provide device name.\n");
		return -EINVAL;
	}

	return rd_exec_dev(rd, cb);
}

int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str)
{
	const struct rd_cmd *c;

	/* First argument in objs table is default variant */
	if (rd_no_arg(rd))
		return cmds->func(rd);

	for (c = cmds + 1; c->cmd; ++c) {
		if (rd_argv_match(rd, c->cmd)) {
			/* Move to next argument */
			rd_arg_inc(rd);
			return c->func(rd);
		}
	}

	pr_err("Unknown %s '%s'.\n", str, rd_argv(rd));
	return 0;
}

void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags)
{
	*seq = time(NULL);

	rd->nlh = mnl_nlmsg_put_header(rd->buff);
	rd->nlh->nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, cmd);
	rd->nlh->nlmsg_seq = *seq;
	rd->nlh->nlmsg_flags = flags;
}

int rd_send_msg(struct rd *rd)
{
	int ret;

	rd->nl = mnl_socket_open(NETLINK_RDMA);
	if (!rd->nl) {
		pr_err("Failed to open NETLINK_RDMA socket\n");
		return -ENODEV;
	}

	ret = mnl_socket_bind(rd->nl, 0, MNL_SOCKET_AUTOPID);
	if (ret < 0) {
		pr_err("Failed to bind socket with err %d\n", ret);
		goto err;
	}

	ret = mnl_socket_sendto(rd->nl, rd->nlh, rd->nlh->nlmsg_len);
	if (ret < 0) {
		pr_err("Failed to send to socket with err %d\n", ret);
		goto err;
	}
	return 0;

err:
	mnl_socket_close(rd->nl);
	return ret;
}

int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq)
{
	int ret;
	unsigned int portid;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	portid = mnl_socket_get_portid(rd->nl);
	do {
		ret = mnl_socket_recvfrom(rd->nl, buf, sizeof(buf));
		if (ret <= 0)
			break;

		ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
	} while (ret > 0);

	if (ret < 0 && !rd->suppress_errors)
		perror("error");

	mnl_socket_close(rd->nl);
	return ret;
}

static int null_cb(const struct nlmsghdr *nlh, void *data)
{
	return MNL_CB_OK;
}

int rd_sendrecv_msg(struct rd *rd, unsigned int seq)
{
	int ret;

	ret = rd_send_msg(rd);
	if (!ret)
		ret = rd_recv_msg(rd, null_cb, rd, seq);
	return ret;
}

static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name)
{
	struct dev_map *dev_map;

	list_for_each_entry(dev_map, &rd->dev_map_list, list)
		if (strcmp(dev_name, dev_map->dev_name) == 0)
			return dev_map;

	return NULL;
}

struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index)
{
	struct dev_map *dev_map;
	char *dev_name;
	char *slash;

	if (rd_no_arg(rd))
		return NULL;

	dev_name = strdup(rd_argv(rd));
	if (allow_port_index) {
		slash = strrchr(dev_name, '/');
		if (slash)
			*slash = '\0';
	}

	dev_map = _dev_map_lookup(rd, dev_name);
	free(dev_name);
	return dev_map;
}

#define nla_type(attr) ((attr)->nla_type & NLA_TYPE_MASK)

void newline(struct rd *rd)
{
	if (rd->json_output)
		jsonw_end_array(rd->jw);
	else
		pr_out("\n");
}

void newline_indent(struct rd *rd)
{
	newline(rd);
	if (!rd->json_output)
		pr_out("    ");
}

static int print_driver_string(struct rd *rd, const char *key_str,
				 const char *val_str)
{
	if (rd->json_output) {
		jsonw_string_field(rd->jw, key_str, val_str);
		return 0;
	} else {
		return pr_out("%s %s ", key_str, val_str);
	}
}

void print_on_off(struct rd *rd, const char *key_str, bool on)
{
	print_driver_string(rd, key_str, (on) ? "on":"off");
}

static int print_driver_s32(struct rd *rd, const char *key_str, int32_t val,
			      enum rdma_nldev_print_type print_type)
{
	if (rd->json_output) {
		jsonw_int_field(rd->jw, key_str, val);
		return 0;
	}
	switch (print_type) {
	case RDMA_NLDEV_PRINT_TYPE_UNSPEC:
		return pr_out("%s %d ", key_str, val);
	case RDMA_NLDEV_PRINT_TYPE_HEX:
		return pr_out("%s 0x%x ", key_str, val);
	default:
		return -EINVAL;
	}
}

static int print_driver_u32(struct rd *rd, const char *key_str, uint32_t val,
			      enum rdma_nldev_print_type print_type)
{
	if (rd->json_output) {
		jsonw_int_field(rd->jw, key_str, val);
		return 0;
	}
	switch (print_type) {
	case RDMA_NLDEV_PRINT_TYPE_UNSPEC:
		return pr_out("%s %u ", key_str, val);
	case RDMA_NLDEV_PRINT_TYPE_HEX:
		return pr_out("%s 0x%x ", key_str, val);
	default:
		return -EINVAL;
	}
}

static int print_driver_s64(struct rd *rd, const char *key_str, int64_t val,
			      enum rdma_nldev_print_type print_type)
{
	if (rd->json_output) {
		jsonw_int_field(rd->jw, key_str, val);
		return 0;
	}
	switch (print_type) {
	case RDMA_NLDEV_PRINT_TYPE_UNSPEC:
		return pr_out("%s %" PRId64 " ", key_str, val);
	case RDMA_NLDEV_PRINT_TYPE_HEX:
		return pr_out("%s 0x%" PRIx64 " ", key_str, val);
	default:
		return -EINVAL;
	}
}

static int print_driver_u64(struct rd *rd, const char *key_str, uint64_t val,
			      enum rdma_nldev_print_type print_type)
{
	if (rd->json_output) {
		jsonw_int_field(rd->jw, key_str, val);
		return 0;
	}
	switch (print_type) {
	case RDMA_NLDEV_PRINT_TYPE_UNSPEC:
		return pr_out("%s %" PRIu64 " ", key_str, val);
	case RDMA_NLDEV_PRINT_TYPE_HEX:
		return pr_out("%s 0x%" PRIx64 " ", key_str, val);
	default:
		return -EINVAL;
	}
}

static int print_driver_entry(struct rd *rd, struct nlattr *key_attr,
				struct nlattr *val_attr,
				enum rdma_nldev_print_type print_type)
{
	int attr_type = nla_type(val_attr);
	int ret = -EINVAL;
	char *key_str;

	if (asprintf(&key_str, "drv_%s", mnl_attr_get_str(key_attr)) == -1)
		return -ENOMEM;

	switch (attr_type) {
	case RDMA_NLDEV_ATTR_DRIVER_STRING:
		ret = print_driver_string(rd, key_str,
					  mnl_attr_get_str(val_attr));
		break;
	case RDMA_NLDEV_ATTR_DRIVER_S32:
		ret = print_driver_s32(rd, key_str, mnl_attr_get_u32(val_attr),
				       print_type);
		break;
	case RDMA_NLDEV_ATTR_DRIVER_U32:
		ret = print_driver_u32(rd, key_str, mnl_attr_get_u32(val_attr),
				       print_type);
		break;
	case RDMA_NLDEV_ATTR_DRIVER_S64:
		ret = print_driver_s64(rd, key_str, mnl_attr_get_u64(val_attr),
				       print_type);
		break;
	case RDMA_NLDEV_ATTR_DRIVER_U64:
		ret = print_driver_u64(rd, key_str, mnl_attr_get_u64(val_attr),
				       print_type);
		break;
	}
	free(key_str);
	return ret;
}

void print_driver_table(struct rd *rd, struct nlattr *tb)
{
	int print_type = RDMA_NLDEV_PRINT_TYPE_UNSPEC;
	struct nlattr *tb_entry, *key = NULL, *val;
	int type, cc = 0;
	int ret;

	if (!rd->show_driver_details || !tb)
		return;

	if (rd->pretty_output)
		newline_indent(rd);

	/*
	 * Driver attrs are tuples of {key, [print-type], value}.
	 * The key must be a string.  If print-type is present, it
	 * defines an alternate printf format type vs the native format
	 * for the attribute.  And the value can be any available
	 * driver type.
	 */
	mnl_attr_for_each_nested(tb_entry, tb) {

		if (cc > MAX_LINE_LENGTH) {
			if (rd->pretty_output)
				newline_indent(rd);
			cc = 0;
		}
		if (rd_attr_check(tb_entry, &type) != MNL_CB_OK)
			return;
		if (!key) {
			if (type != MNL_TYPE_NUL_STRING)
				return;
			key = tb_entry;
		} else if (type == MNL_TYPE_U8) {
			print_type = mnl_attr_get_u8(tb_entry);
		} else {
			val = tb_entry;
			ret = print_driver_entry(rd, key, val, print_type);
			if (ret < 0)
				return;
			cc += ret;
			print_type = RDMA_NLDEV_PRINT_TYPE_UNSPEC;
			key = NULL;
		}
	}
	return;
}
