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

#include "res.h"
#include <inttypes.h>

static void print_qp_type(struct rd *rd, uint32_t val)
{
	print_color_string(PRINT_ANY, COLOR_NONE, "qp-type", "qp-type %s ",
			   qp_types_to_str(val));
}

static const char *cm_id_state_to_str(uint8_t idx)
{
	static const char *const cm_id_states_str[] = {
		"IDLE",		  "ADDR_QUERY",     "ADDR_RESOLVED",
		"ROUTE_QUERY",    "ROUTE_RESOLVED", "CONNECT",
		"DISCONNECT",     "ADDR_BOUND",     "LISTEN",
		"DEVICE_REMOVAL", "DESTROYING"
	};

	if (idx < ARRAY_SIZE(cm_id_states_str))
		return cm_id_states_str[idx];
	return "UNKNOWN";
}

static const char *cm_id_ps_to_str(uint32_t ps)
{
	switch (ps) {
	case RDMA_PS_IPOIB:
		return "IPoIB";
	case RDMA_PS_IB:
		return "IPoIB";
	case RDMA_PS_TCP:
		return "TCP";
	case RDMA_PS_UDP:
		return "UDP";
	default:
		return "---";
	}
}

static void print_cm_id_state(struct rd *rd, uint8_t state)
{
	print_color_string(PRINT_ANY, COLOR_NONE, "state", "state %s ",
			   cm_id_state_to_str(state));
}

static void print_ps(struct rd *rd, uint32_t ps)
{
	print_color_string(PRINT_ANY, COLOR_NONE, "ps", "ps %s ",
			   cm_id_ps_to_str(ps));
}

static void print_ipaddr(struct rd *rd, const char *key, char *addrstr,
			 uint16_t port)
{
	int name_size = INET6_ADDRSTRLEN + strlen(":65535");
	char json_name[name_size];

	snprintf(json_name, name_size, "%s:%u", addrstr, port);
	print_color_string(PRINT_ANY, COLOR_NONE, key, key, json_name);
	print_color_string(PRINT_FP, COLOR_NONE, NULL, " %s:", addrstr);
	print_color_uint(PRINT_FP, COLOR_NONE, NULL, "%u ", port);
}

static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
{
	struct __kernel_sockaddr_storage *addr;

	addr = (struct __kernel_sockaddr_storage *)mnl_attr_get_payload(
		nla_line);
	switch (addr->ss_family) {
	case AF_INET: {
		struct sockaddr_in *sin = (struct sockaddr_in *)addr;

		if (!inet_ntop(AF_INET, (const void *)&sin->sin_addr, addr_str,
			       INET6_ADDRSTRLEN))
			return -EINVAL;
		*port = ntohs(sin->sin_port);
		break;
	}
	case AF_INET6: {
		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;

		if (!inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr,
			       addr_str, INET6_ADDRSTRLEN))
			return -EINVAL;
		*port = ntohs(sin6->sin6_port);
		break;
	}
	default:
		return -EINVAL;
	}
	return 0;
}
static int res_cm_id_line(struct rd *rd, const char *name, int idx,
		       struct nlattr **nla_line)
{
	char src_addr_str[INET6_ADDRSTRLEN];
	char dst_addr_str[INET6_ADDRSTRLEN];
	uint16_t src_port, dst_port;
	uint32_t port = 0, pid = 0;
	uint8_t type = 0, state;
	uint32_t lqpn = 0, ps;
	uint32_t cm_idn = 0;
	char *comm = NULL;

	if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
	    !nla_line[RDMA_NLDEV_ATTR_RES_PS])
		return MNL_CB_ERROR;

	if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
		port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);

	if (port && port != rd->port_idx)
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
		lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);

	if (rd_is_filtered_attr(rd, "lqpn", lqpn,
				nla_line[RDMA_NLDEV_ATTR_RES_LQPN]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
		type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
	if (rd_is_string_filtered_attr(rd, "qp-type", qp_types_to_str(type),
				       nla_line[RDMA_NLDEV_ATTR_RES_TYPE]))
		goto out;

	ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
	if (rd_is_string_filtered_attr(rd, "ps", cm_id_ps_to_str(ps),
				       nla_line[RDMA_NLDEV_ATTR_RES_PS]))
		goto out;

	state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
	if (rd_is_string_filtered_attr(rd, "state", cm_id_state_to_str(state),
				       nla_line[RDMA_NLDEV_ATTR_RES_STATE]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
			    src_addr_str, &src_port))
			goto out;
	if (rd_is_string_filtered_attr(rd, "src-addr", src_addr_str,
				       nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]))
		goto out;
	if (rd_is_filtered_attr(rd, "src-port", src_port,
				nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
			    dst_addr_str, &dst_port))
			goto out;
	if (rd_is_string_filtered_attr(rd, "dst-addr", dst_addr_str,
				       nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]))
		goto out;
	if (rd_is_filtered_attr(rd, "dst-port", dst_port,
				nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
		comm = get_task_name(pid);
	}

	if (rd_is_filtered_attr(rd, "pid", pid,
				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
		cm_idn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
	if (rd_is_filtered_attr(rd, "cm-idn", cm_idn,
				nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]))
		goto out;

	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
		/* discard const from mnl_attr_get_str */
		comm = (char *)mnl_attr_get_str(
			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
	}

	open_json_object(NULL);
	print_link(rd, idx, name, port, nla_line);
	res_print_uint(rd, "cm-idn", cm_idn,
		       nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
	res_print_uint(rd, "lqpn", lqpn, nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
		print_qp_type(rd, type);
	print_cm_id_state(rd, state);
	print_ps(rd, ps);
	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
	print_comm(rd, comm, nla_line);

	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
		print_ipaddr(rd, "src-addr", src_addr_str, src_port);
	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
		print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port);

	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
	newline(rd);

out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
		free(comm);
	return MNL_CB_OK;
}

int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
	struct rd *rd = data;
	const char *name;
	int idx;

	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
		return MNL_CB_ERROR;

	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);

	return res_cm_id_line(rd, name, idx, tb);
}

int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
	struct nlattr *nla_table, *nla_entry;
	struct rd *rd = data;
	int ret = MNL_CB_OK;
	const char *name;
	int idx;

	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
	    !tb[RDMA_NLDEV_ATTR_RES_CM_ID])
		return MNL_CB_ERROR;

	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];

	mnl_attr_for_each_nested(nla_entry, nla_table) {
		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};

		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
		if (ret != MNL_CB_OK)
			break;

		ret = res_cm_id_line(rd, name, idx, nla_line);
		if (ret != MNL_CB_OK)
			break;
	}
	return ret;
}
