// 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)
{
	if (rd->json_output)
		jsonw_string_field(rd->jw, "qp-type", qp_types_to_str(val));
	else
		pr_out("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)
{
	if (rd->json_output) {
		jsonw_string_field(rd->jw, "state", cm_id_state_to_str(state));
		return;
	}
	pr_out("state %s ", cm_id_state_to_str(state));
}

static void print_ps(struct rd *rd, uint32_t ps)
{
	if (rd->json_output) {
		jsonw_string_field(rd->jw, "ps", cm_id_ps_to_str(ps));
		return;
	}
	pr_out("ps %s ", cm_id_ps_to_str(ps));
}

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

		snprintf(json_name, name_size, "%s:%u", addrstr, port);
		jsonw_string_field(rd->jw, key, json_name);
		return;
	}
	pr_out("%s %s:%u ", key, addrstr, 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] ||
	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
		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]);
	}

	if (rd->json_output)
		jsonw_start_array(rd->jw);

	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;
}
