// SPDX-License-Identifier: GPL-2.0
/*
 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
 *
 *  Generic netlink support functions to configure an SMC-R PNET table
 *
 *  Copyright IBM Corp. 2016
 *
 *  Author(s):  Thomas Richter <tmricht@linux.vnet.ibm.com>
 */

#include <linux/module.h>
#include <linux/list.h>
#include <linux/ctype.h>
#include <net/netlink.h>
#include <net/genetlink.h>

#include <uapi/linux/if.h>
#include <uapi/linux/smc.h>

#include <rdma/ib_verbs.h>

#include "smc_pnet.h"
#include "smc_ib.h"
#include "smc_ism.h"

static struct nla_policy smc_pnet_policy[SMC_PNETID_MAX + 1] = {
	[SMC_PNETID_NAME] = {
		.type = NLA_NUL_STRING,
		.len = SMC_MAX_PNETID_LEN
	},
	[SMC_PNETID_ETHNAME] = {
		.type = NLA_NUL_STRING,
		.len = IFNAMSIZ - 1
	},
	[SMC_PNETID_IBNAME] = {
		.type = NLA_NUL_STRING,
		.len = IB_DEVICE_NAME_MAX - 1
	},
	[SMC_PNETID_IBPORT] = { .type = NLA_U8 }
};

static struct genl_family smc_pnet_nl_family;

/**
 * struct smc_pnettable - SMC PNET table anchor
 * @lock: Lock for list action
 * @pnetlist: List of PNETIDs
 */
static struct smc_pnettable {
	rwlock_t lock;
	struct list_head pnetlist;
} smc_pnettable = {
	.pnetlist = LIST_HEAD_INIT(smc_pnettable.pnetlist),
	.lock = __RW_LOCK_UNLOCKED(smc_pnettable.lock)
};

/**
 * struct smc_pnetentry - pnet identifier name entry
 * @list: List node.
 * @pnet_name: Pnet identifier name
 * @ndev: pointer to network device.
 * @smcibdev: Pointer to IB device.
 */
struct smc_pnetentry {
	struct list_head list;
	char pnet_name[SMC_MAX_PNETID_LEN + 1];
	struct net_device *ndev;
	struct smc_ib_device *smcibdev;
	u8 ib_port;
};

/* Check if two RDMA device entries are identical. Use device name and port
 * number for comparison.
 */
static bool smc_pnet_same_ibname(struct smc_pnetentry *pnetelem, char *ibname,
				 u8 ibport)
{
	return pnetelem->ib_port == ibport &&
	       !strncmp(pnetelem->smcibdev->ibdev->name, ibname,
			sizeof(pnetelem->smcibdev->ibdev->name));
}

/* Find a pnetid in the pnet table.
 */
static struct smc_pnetentry *smc_pnet_find_pnetid(char *pnet_name)
{
	struct smc_pnetentry *pnetelem, *found_pnetelem = NULL;

	read_lock(&smc_pnettable.lock);
	list_for_each_entry(pnetelem, &smc_pnettable.pnetlist, list) {
		if (!strncmp(pnetelem->pnet_name, pnet_name,
			     sizeof(pnetelem->pnet_name))) {
			found_pnetelem = pnetelem;
			break;
		}
	}
	read_unlock(&smc_pnettable.lock);
	return found_pnetelem;
}

/* Remove a pnetid from the pnet table.
 */
static int smc_pnet_remove_by_pnetid(char *pnet_name)
{
	struct smc_pnetentry *pnetelem, *tmp_pe;
	int rc = -ENOENT;

	write_lock(&smc_pnettable.lock);
	list_for_each_entry_safe(pnetelem, tmp_pe, &smc_pnettable.pnetlist,
				 list) {
		if (!strncmp(pnetelem->pnet_name, pnet_name,
			     sizeof(pnetelem->pnet_name))) {
			list_del(&pnetelem->list);
			dev_put(pnetelem->ndev);
			kfree(pnetelem);
			rc = 0;
			break;
		}
	}
	write_unlock(&smc_pnettable.lock);
	return rc;
}

/* Remove a pnet entry mentioning a given network device from the pnet table.
 */
static int smc_pnet_remove_by_ndev(struct net_device *ndev)
{
	struct smc_pnetentry *pnetelem, *tmp_pe;
	int rc = -ENOENT;

	write_lock(&smc_pnettable.lock);
	list_for_each_entry_safe(pnetelem, tmp_pe, &smc_pnettable.pnetlist,
				 list) {
		if (pnetelem->ndev == ndev) {
			list_del(&pnetelem->list);
			dev_put(pnetelem->ndev);
			kfree(pnetelem);
			rc = 0;
			break;
		}
	}
	write_unlock(&smc_pnettable.lock);
	return rc;
}

/* Remove a pnet entry mentioning a given ib device from the pnet table.
 */
int smc_pnet_remove_by_ibdev(struct smc_ib_device *ibdev)
{
	struct smc_pnetentry *pnetelem, *tmp_pe;
	int rc = -ENOENT;

	write_lock(&smc_pnettable.lock);
	list_for_each_entry_safe(pnetelem, tmp_pe, &smc_pnettable.pnetlist,
				 list) {
		if (pnetelem->smcibdev == ibdev) {
			list_del(&pnetelem->list);
			dev_put(pnetelem->ndev);
			kfree(pnetelem);
			rc = 0;
			break;
		}
	}
	write_unlock(&smc_pnettable.lock);
	return rc;
}

/* Append a pnetid to the end of the pnet table if not already on this list.
 */
static int smc_pnet_enter(struct smc_pnetentry *new_pnetelem)
{
	struct smc_pnetentry *pnetelem;
	int rc = -EEXIST;

	write_lock(&smc_pnettable.lock);
	list_for_each_entry(pnetelem, &smc_pnettable.pnetlist, list) {
		if (!strncmp(pnetelem->pnet_name, new_pnetelem->pnet_name,
			     sizeof(new_pnetelem->pnet_name)) ||
		    !strncmp(pnetelem->ndev->name, new_pnetelem->ndev->name,
			     sizeof(new_pnetelem->ndev->name)) ||
		    smc_pnet_same_ibname(pnetelem,
					 new_pnetelem->smcibdev->ibdev->name,
					 new_pnetelem->ib_port)) {
			dev_put(pnetelem->ndev);
			goto found;
		}
	}
	list_add_tail(&new_pnetelem->list, &smc_pnettable.pnetlist);
	rc = 0;
found:
	write_unlock(&smc_pnettable.lock);
	return rc;
}

/* The limit for pnetid is 16 characters.
 * Valid characters should be (single-byte character set) a-z, A-Z, 0-9.
 * Lower case letters are converted to upper case.
 * Interior blanks should not be used.
 */
static bool smc_pnetid_valid(const char *pnet_name, char *pnetid)
{
	char *bf = skip_spaces(pnet_name);
	size_t len = strlen(bf);
	char *end = bf + len;

	if (!len)
		return false;
	while (--end >= bf && isspace(*end))
		;
	if (end - bf >= SMC_MAX_PNETID_LEN)
		return false;
	while (bf <= end) {
		if (!isalnum(*bf))
			return false;
		*pnetid++ = islower(*bf) ? toupper(*bf) : *bf;
		bf++;
	}
	*pnetid = '\0';
	return true;
}

/* Find an infiniband device by a given name. The device might not exist. */
static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
{
	struct smc_ib_device *ibdev;

	spin_lock(&smc_ib_devices.lock);
	list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
		if (!strncmp(ibdev->ibdev->name, ib_name,
			     sizeof(ibdev->ibdev->name))) {
			goto out;
		}
	}
	ibdev = NULL;
out:
	spin_unlock(&smc_ib_devices.lock);
	return ibdev;
}

/* Parse the supplied netlink attributes and fill a pnetentry structure.
 * For ethernet and infiniband device names verify that the devices exist.
 */
static int smc_pnet_fill_entry(struct net *net, struct smc_pnetentry *pnetelem,
			       struct nlattr *tb[])
{
	char *string, *ibname;
	int rc;

	memset(pnetelem, 0, sizeof(*pnetelem));
	INIT_LIST_HEAD(&pnetelem->list);

	rc = -EINVAL;
	if (!tb[SMC_PNETID_NAME])
		goto error;
	string = (char *)nla_data(tb[SMC_PNETID_NAME]);
	if (!smc_pnetid_valid(string, pnetelem->pnet_name))
		goto error;

	rc = -EINVAL;
	if (!tb[SMC_PNETID_ETHNAME])
		goto error;
	rc = -ENOENT;
	string = (char *)nla_data(tb[SMC_PNETID_ETHNAME]);
	pnetelem->ndev = dev_get_by_name(net, string);
	if (!pnetelem->ndev)
		goto error;

	rc = -EINVAL;
	if (!tb[SMC_PNETID_IBNAME])
		goto error;
	rc = -ENOENT;
	ibname = (char *)nla_data(tb[SMC_PNETID_IBNAME]);
	ibname = strim(ibname);
	pnetelem->smcibdev = smc_pnet_find_ib(ibname);
	if (!pnetelem->smcibdev)
		goto error;

	rc = -EINVAL;
	if (!tb[SMC_PNETID_IBPORT])
		goto error;
	pnetelem->ib_port = nla_get_u8(tb[SMC_PNETID_IBPORT]);
	if (pnetelem->ib_port < 1 || pnetelem->ib_port > SMC_MAX_PORTS)
		goto error;

	return 0;

error:
	if (pnetelem->ndev)
		dev_put(pnetelem->ndev);
	return rc;
}

/* Convert an smc_pnetentry to a netlink attribute sequence */
static int smc_pnet_set_nla(struct sk_buff *msg, struct smc_pnetentry *pnetelem)
{
	if (nla_put_string(msg, SMC_PNETID_NAME, pnetelem->pnet_name) ||
	    nla_put_string(msg, SMC_PNETID_ETHNAME, pnetelem->ndev->name) ||
	    nla_put_string(msg, SMC_PNETID_IBNAME,
			   pnetelem->smcibdev->ibdev->name) ||
	    nla_put_u8(msg, SMC_PNETID_IBPORT, pnetelem->ib_port))
		return -1;
	return 0;
}

/* Retrieve one PNETID entry */
static int smc_pnet_get(struct sk_buff *skb, struct genl_info *info)
{
	struct smc_pnetentry *pnetelem;
	struct sk_buff *msg;
	void *hdr;
	int rc;

	if (!info->attrs[SMC_PNETID_NAME])
		return -EINVAL;
	pnetelem = smc_pnet_find_pnetid(
				(char *)nla_data(info->attrs[SMC_PNETID_NAME]));
	if (!pnetelem)
		return -ENOENT;
	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
			  &smc_pnet_nl_family, 0, SMC_PNETID_GET);
	if (!hdr) {
		rc = -EMSGSIZE;
		goto err_out;
	}

	if (smc_pnet_set_nla(msg, pnetelem)) {
		rc = -ENOBUFS;
		goto err_out;
	}

	genlmsg_end(msg, hdr);
	return genlmsg_reply(msg, info);

err_out:
	nlmsg_free(msg);
	return rc;
}

static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info)
{
	struct net *net = genl_info_net(info);
	struct smc_pnetentry *pnetelem;
	int rc;

	pnetelem = kzalloc(sizeof(*pnetelem), GFP_KERNEL);
	if (!pnetelem)
		return -ENOMEM;
	rc = smc_pnet_fill_entry(net, pnetelem, info->attrs);
	if (!rc)
		rc = smc_pnet_enter(pnetelem);
	if (rc) {
		kfree(pnetelem);
		return rc;
	}
	return rc;
}

static int smc_pnet_del(struct sk_buff *skb, struct genl_info *info)
{
	if (!info->attrs[SMC_PNETID_NAME])
		return -EINVAL;
	return smc_pnet_remove_by_pnetid(
				(char *)nla_data(info->attrs[SMC_PNETID_NAME]));
}

static int smc_pnet_dump_start(struct netlink_callback *cb)
{
	cb->args[0] = 0;
	return 0;
}

static int smc_pnet_dumpinfo(struct sk_buff *skb,
			     u32 portid, u32 seq, u32 flags,
			     struct smc_pnetentry *pnetelem)
{
	void *hdr;

	hdr = genlmsg_put(skb, portid, seq, &smc_pnet_nl_family,
			  flags, SMC_PNETID_GET);
	if (!hdr)
		return -ENOMEM;
	if (smc_pnet_set_nla(skb, pnetelem) < 0) {
		genlmsg_cancel(skb, hdr);
		return -EMSGSIZE;
	}
	genlmsg_end(skb, hdr);
	return 0;
}

static int smc_pnet_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_pnetentry *pnetelem;
	int idx = 0;

	read_lock(&smc_pnettable.lock);
	list_for_each_entry(pnetelem, &smc_pnettable.pnetlist, list) {
		if (idx++ < cb->args[0])
			continue;
		if (smc_pnet_dumpinfo(skb, NETLINK_CB(cb->skb).portid,
				      cb->nlh->nlmsg_seq, NLM_F_MULTI,
				      pnetelem)) {
			--idx;
			break;
		}
	}
	cb->args[0] = idx;
	read_unlock(&smc_pnettable.lock);
	return skb->len;
}

/* Remove and delete all pnetids from pnet table.
 */
static int smc_pnet_flush(struct sk_buff *skb, struct genl_info *info)
{
	struct smc_pnetentry *pnetelem, *tmp_pe;

	write_lock(&smc_pnettable.lock);
	list_for_each_entry_safe(pnetelem, tmp_pe, &smc_pnettable.pnetlist,
				 list) {
		list_del(&pnetelem->list);
		dev_put(pnetelem->ndev);
		kfree(pnetelem);
	}
	write_unlock(&smc_pnettable.lock);
	return 0;
}

/* SMC_PNETID generic netlink operation definition */
static const struct genl_ops smc_pnet_ops[] = {
	{
		.cmd = SMC_PNETID_GET,
		.flags = GENL_ADMIN_PERM,
		.policy = smc_pnet_policy,
		.doit = smc_pnet_get,
		.dumpit = smc_pnet_dump,
		.start = smc_pnet_dump_start
	},
	{
		.cmd = SMC_PNETID_ADD,
		.flags = GENL_ADMIN_PERM,
		.policy = smc_pnet_policy,
		.doit = smc_pnet_add
	},
	{
		.cmd = SMC_PNETID_DEL,
		.flags = GENL_ADMIN_PERM,
		.policy = smc_pnet_policy,
		.doit = smc_pnet_del
	},
	{
		.cmd = SMC_PNETID_FLUSH,
		.flags = GENL_ADMIN_PERM,
		.policy = smc_pnet_policy,
		.doit = smc_pnet_flush
	}
};

/* SMC_PNETID family definition */
static struct genl_family smc_pnet_nl_family __ro_after_init = {
	.hdrsize = 0,
	.name = SMCR_GENL_FAMILY_NAME,
	.version = SMCR_GENL_FAMILY_VERSION,
	.maxattr = SMC_PNETID_MAX,
	.netnsok = true,
	.module = THIS_MODULE,
	.ops = smc_pnet_ops,
	.n_ops =  ARRAY_SIZE(smc_pnet_ops)
};

static int smc_pnet_netdev_event(struct notifier_block *this,
				 unsigned long event, void *ptr)
{
	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);

	switch (event) {
	case NETDEV_REBOOT:
	case NETDEV_UNREGISTER:
		smc_pnet_remove_by_ndev(event_dev);
		return NOTIFY_OK;
	default:
		return NOTIFY_DONE;
	}
}

static struct notifier_block smc_netdev_notifier = {
	.notifier_call = smc_pnet_netdev_event
};

int __init smc_pnet_init(void)
{
	int rc;

	rc = genl_register_family(&smc_pnet_nl_family);
	if (rc)
		return rc;
	rc = register_netdevice_notifier(&smc_netdev_notifier);
	if (rc)
		genl_unregister_family(&smc_pnet_nl_family);
	return rc;
}

void smc_pnet_exit(void)
{
	smc_pnet_flush(NULL, NULL);
	unregister_netdevice_notifier(&smc_netdev_notifier);
	genl_unregister_family(&smc_pnet_nl_family);
}

/* Determine one base device for stacked net devices.
 * If the lower device level contains more than one devices
 * (for instance with bonding slaves), just the first device
 * is used to reach a base device.
 */
static struct net_device *pnet_find_base_ndev(struct net_device *ndev)
{
	int i, nest_lvl;

	rtnl_lock();
	nest_lvl = dev_get_nest_level(ndev);
	for (i = 0; i < nest_lvl; i++) {
		struct list_head *lower = &ndev->adj_list.lower;

		if (list_empty(lower))
			break;
		lower = lower->next;
		ndev = netdev_lower_get_next(ndev, &lower);
	}
	rtnl_unlock();
	return ndev;
}

/* Determine the corresponding IB device port based on the hardware PNETID.
 * Searching stops at the first matching active IB device port with vlan_id
 * configured.
 */
static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
					 struct smc_ib_device **smcibdev,
					 u8 *ibport, unsigned short vlan_id,
					 u8 gid[])
{
	u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
	struct smc_ib_device *ibdev;
	int i;

	ndev = pnet_find_base_ndev(ndev);
	if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
				   ndev_pnetid))
		return; /* pnetid could not be determined */

	spin_lock(&smc_ib_devices.lock);
	list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
		for (i = 1; i <= SMC_MAX_PORTS; i++) {
			if (!rdma_is_port_valid(ibdev->ibdev, i))
				continue;
			if (!memcmp(ibdev->pnetid[i - 1], ndev_pnetid,
				    SMC_MAX_PNETID_LEN) &&
			    smc_ib_port_active(ibdev, i) &&
			    !smc_ib_determine_gid(ibdev, i, vlan_id, gid,
						  NULL))  {
				*smcibdev = ibdev;
				*ibport = i;
				goto out;
			}
		}
	}
out:
	spin_unlock(&smc_ib_devices.lock);
}

static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,
					struct smcd_dev **smcismdev)
{
	u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
	struct smcd_dev *ismdev;

	ndev = pnet_find_base_ndev(ndev);
	if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port,
				   ndev_pnetid))
		return; /* pnetid could not be determined */

	spin_lock(&smcd_dev_list.lock);
	list_for_each_entry(ismdev, &smcd_dev_list.list, list) {
		if (!memcmp(ismdev->pnetid, ndev_pnetid, SMC_MAX_PNETID_LEN)) {
			*smcismdev = ismdev;
			break;
		}
	}
	spin_unlock(&smcd_dev_list.lock);
}

/* Lookup of coupled ib_device via SMC pnet table */
static void smc_pnet_find_roce_by_table(struct net_device *netdev,
					struct smc_ib_device **smcibdev,
					u8 *ibport, unsigned short vlan_id,
					u8 gid[])
{
	struct smc_pnetentry *pnetelem;

	read_lock(&smc_pnettable.lock);
	list_for_each_entry(pnetelem, &smc_pnettable.pnetlist, list) {
		if (netdev == pnetelem->ndev) {
			if (smc_ib_port_active(pnetelem->smcibdev,
					       pnetelem->ib_port) &&
			    !smc_ib_determine_gid(pnetelem->smcibdev,
						  pnetelem->ib_port, vlan_id,
						  gid, NULL)) {
				*smcibdev = pnetelem->smcibdev;
				*ibport = pnetelem->ib_port;
			}
			break;
		}
	}
	read_unlock(&smc_pnettable.lock);
}

/* PNET table analysis for a given sock:
 * determine ib_device and port belonging to used internal TCP socket
 * ethernet interface.
 */
void smc_pnet_find_roce_resource(struct sock *sk,
				 struct smc_ib_device **smcibdev, u8 *ibport,
				 unsigned short vlan_id, u8 gid[])
{
	struct dst_entry *dst = sk_dst_get(sk);

	*smcibdev = NULL;
	*ibport = 0;

	if (!dst)
		goto out;
	if (!dst->dev)
		goto out_rel;

	/* if possible, lookup via hardware-defined pnetid */
	smc_pnet_find_roce_by_pnetid(dst->dev, smcibdev, ibport, vlan_id, gid);
	if (*smcibdev)
		goto out_rel;

	/* lookup via SMC PNET table */
	smc_pnet_find_roce_by_table(dst->dev, smcibdev, ibport, vlan_id, gid);

out_rel:
	dst_release(dst);
out:
	return;
}

void smc_pnet_find_ism_resource(struct sock *sk, struct smcd_dev **smcismdev)
{
	struct dst_entry *dst = sk_dst_get(sk);

	*smcismdev = NULL;
	if (!dst)
		goto out;
	if (!dst->dev)
		goto out_rel;

	/* if possible, lookup via hardware-defined pnetid */
	smc_pnet_find_ism_by_pnetid(dst->dev, smcismdev);

out_rel:
	dst_release(dst);
out:
	return;
}
