// SPDX-License-Identifier: GPL-2.0
/*
 * Management Component Transport Protocol (MCTP) - device implementation.
 *
 * Copyright (c) 2021 Code Construct
 * Copyright (c) 2021 Google
 */

#include <linux/if_arp.h>
#include <linux/if_link.h>
#include <linux/mctp.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/rtnetlink.h>

#include <net/addrconf.h>
#include <net/netlink.h>
#include <net/mctp.h>
#include <net/mctpdevice.h>
#include <net/sock.h>

struct mctp_dump_cb {
	unsigned long ifindex;
	size_t a_idx;
};

/* unlocked: caller must hold rcu_read_lock.
 * Returned mctp_dev has its refcount incremented, or NULL if unset.
 */
struct mctp_dev *__mctp_dev_get(const struct net_device *dev)
{
	struct mctp_dev *mdev = rcu_dereference(dev->mctp_ptr);

	/* RCU guarantees that any mdev is still live.
	 * Zero refcount implies a pending free, return NULL.
	 */
	if (mdev)
		if (!refcount_inc_not_zero(&mdev->refs))
			return NULL;
	return mdev;
}

/* Returned mctp_dev does not have refcount incremented. The returned pointer
 * remains live while rtnl_lock is held, as that prevents mctp_unregister()
 */
struct mctp_dev *mctp_dev_get_rtnl(const struct net_device *dev)
{
	return rtnl_dereference(dev->mctp_ptr);
}

static int mctp_addrinfo_size(void)
{
	return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
		+ nla_total_size(1) // IFA_LOCAL
		+ nla_total_size(1) // IFA_ADDRESS
		;
}

/* flag should be NLM_F_MULTI for dump calls */
static int mctp_fill_addrinfo(struct sk_buff *skb,
			      struct mctp_dev *mdev, mctp_eid_t eid,
			      int msg_type, u32 portid, u32 seq, int flag)
{
	struct ifaddrmsg *hdr;
	struct nlmsghdr *nlh;

	nlh = nlmsg_put(skb, portid, seq,
			msg_type, sizeof(*hdr), flag);
	if (!nlh)
		return -EMSGSIZE;

	hdr = nlmsg_data(nlh);
	hdr->ifa_family = AF_MCTP;
	hdr->ifa_prefixlen = 0;
	hdr->ifa_flags = 0;
	hdr->ifa_scope = 0;
	hdr->ifa_index = mdev->dev->ifindex;

	if (nla_put_u8(skb, IFA_LOCAL, eid))
		goto cancel;

	if (nla_put_u8(skb, IFA_ADDRESS, eid))
		goto cancel;

	nlmsg_end(skb, nlh);

	return 0;

cancel:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}

static int mctp_dump_dev_addrinfo(struct mctp_dev *mdev, struct sk_buff *skb,
				  struct netlink_callback *cb)
{
	struct mctp_dump_cb *mcb = (void *)cb->ctx;
	u32 portid, seq;
	int rc = 0;

	portid = NETLINK_CB(cb->skb).portid;
	seq = cb->nlh->nlmsg_seq;
	for (; mcb->a_idx < mdev->num_addrs; mcb->a_idx++) {
		rc = mctp_fill_addrinfo(skb, mdev, mdev->addrs[mcb->a_idx],
					RTM_NEWADDR, portid, seq, NLM_F_MULTI);
		if (rc < 0)
			break;
	}

	return rc;
}

static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct mctp_dump_cb *mcb = (void *)cb->ctx;
	struct net *net = sock_net(skb->sk);
	struct net_device *dev;
	struct ifaddrmsg *hdr;
	struct mctp_dev *mdev;
	int ifindex, rc;

	hdr = nlmsg_data(cb->nlh);
	// filter by ifindex if requested
	ifindex = hdr->ifa_index;

	rcu_read_lock();
	for_each_netdev_dump(net, dev, mcb->ifindex) {
		if (ifindex && ifindex != dev->ifindex)
			continue;
		mdev = __mctp_dev_get(dev);
		if (!mdev)
			continue;
		rc = mctp_dump_dev_addrinfo(mdev, skb, cb);
		mctp_dev_put(mdev);
		if (rc < 0)
			break;
		mcb->a_idx = 0;
	}
	rcu_read_unlock();

	return skb->len;
}

static void mctp_addr_notify(struct mctp_dev *mdev, mctp_eid_t eid, int msg_type,
			     struct sk_buff *req_skb, struct nlmsghdr *req_nlh)
{
	u32 portid = NETLINK_CB(req_skb).portid;
	struct net *net = dev_net(mdev->dev);
	struct sk_buff *skb;
	int rc = -ENOBUFS;

	skb = nlmsg_new(mctp_addrinfo_size(), GFP_KERNEL);
	if (!skb)
		goto out;

	rc = mctp_fill_addrinfo(skb, mdev, eid, msg_type,
				portid, req_nlh->nlmsg_seq, 0);
	if (rc < 0) {
		WARN_ON_ONCE(rc == -EMSGSIZE);
		goto out;
	}

	rtnl_notify(skb, net, portid, RTNLGRP_MCTP_IFADDR, req_nlh, GFP_KERNEL);
	return;
out:
	kfree_skb(skb);
	rtnl_set_sk_err(net, RTNLGRP_MCTP_IFADDR, rc);
}

static const struct nla_policy ifa_mctp_policy[IFA_MAX + 1] = {
	[IFA_ADDRESS]		= { .type = NLA_U8 },
	[IFA_LOCAL]		= { .type = NLA_U8 },
};

static int mctp_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
			    struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct nlattr *tb[IFA_MAX + 1];
	struct net_device *dev;
	struct mctp_addr *addr;
	struct mctp_dev *mdev;
	struct ifaddrmsg *ifm;
	unsigned long flags;
	u8 *tmp_addrs;
	int rc;

	rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_mctp_policy,
			 extack);
	if (rc < 0)
		return rc;

	ifm = nlmsg_data(nlh);

	if (tb[IFA_LOCAL])
		addr = nla_data(tb[IFA_LOCAL]);
	else if (tb[IFA_ADDRESS])
		addr = nla_data(tb[IFA_ADDRESS]);
	else
		return -EINVAL;

	/* find device */
	dev = __dev_get_by_index(net, ifm->ifa_index);
	if (!dev)
		return -ENODEV;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return -ENODEV;

	if (!mctp_address_unicast(addr->s_addr))
		return -EINVAL;

	/* Prevent duplicates. Under RTNL so don't need to lock for reading */
	if (memchr(mdev->addrs, addr->s_addr, mdev->num_addrs))
		return -EEXIST;

	tmp_addrs = kmalloc(mdev->num_addrs + 1, GFP_KERNEL);
	if (!tmp_addrs)
		return -ENOMEM;
	memcpy(tmp_addrs, mdev->addrs, mdev->num_addrs);
	tmp_addrs[mdev->num_addrs] = addr->s_addr;

	/* Lock to write */
	spin_lock_irqsave(&mdev->addrs_lock, flags);
	mdev->num_addrs++;
	swap(mdev->addrs, tmp_addrs);
	spin_unlock_irqrestore(&mdev->addrs_lock, flags);

	kfree(tmp_addrs);

	mctp_addr_notify(mdev, addr->s_addr, RTM_NEWADDR, skb, nlh);
	mctp_route_add_local(mdev, addr->s_addr);

	return 0;
}

static int mctp_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
			    struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct nlattr *tb[IFA_MAX + 1];
	struct net_device *dev;
	struct mctp_addr *addr;
	struct mctp_dev *mdev;
	struct ifaddrmsg *ifm;
	unsigned long flags;
	u8 *pos;
	int rc;

	rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_mctp_policy,
			 extack);
	if (rc < 0)
		return rc;

	ifm = nlmsg_data(nlh);

	if (tb[IFA_LOCAL])
		addr = nla_data(tb[IFA_LOCAL]);
	else if (tb[IFA_ADDRESS])
		addr = nla_data(tb[IFA_ADDRESS]);
	else
		return -EINVAL;

	/* find device */
	dev = __dev_get_by_index(net, ifm->ifa_index);
	if (!dev)
		return -ENODEV;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return -ENODEV;

	pos = memchr(mdev->addrs, addr->s_addr, mdev->num_addrs);
	if (!pos)
		return -ENOENT;

	rc = mctp_route_remove_local(mdev, addr->s_addr);
	// we can ignore -ENOENT in the case a route was already removed
	if (rc < 0 && rc != -ENOENT)
		return rc;

	spin_lock_irqsave(&mdev->addrs_lock, flags);
	memmove(pos, pos + 1, mdev->num_addrs - 1 - (pos - mdev->addrs));
	mdev->num_addrs--;
	spin_unlock_irqrestore(&mdev->addrs_lock, flags);

	mctp_addr_notify(mdev, addr->s_addr, RTM_DELADDR, skb, nlh);

	return 0;
}

void mctp_dev_hold(struct mctp_dev *mdev)
{
	refcount_inc(&mdev->refs);
}

void mctp_dev_put(struct mctp_dev *mdev)
{
	if (mdev && refcount_dec_and_test(&mdev->refs)) {
		kfree(mdev->addrs);
		dev_put(mdev->dev);
		kfree_rcu(mdev, rcu);
	}
}

void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key)
	__must_hold(&key->lock)
{
	if (!dev)
		return;
	if (dev->ops && dev->ops->release_flow)
		dev->ops->release_flow(dev, key);
	key->dev = NULL;
	mctp_dev_put(dev);
}

void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key)
	__must_hold(&key->lock)
{
	mctp_dev_hold(dev);
	key->dev = dev;
}

static struct mctp_dev *mctp_add_dev(struct net_device *dev)
{
	struct mctp_dev *mdev;

	ASSERT_RTNL();

	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
	if (!mdev)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&mdev->addrs_lock);

	mdev->net = mctp_default_net(dev_net(dev));

	/* associate to net_device */
	refcount_set(&mdev->refs, 1);
	rcu_assign_pointer(dev->mctp_ptr, mdev);

	dev_hold(dev);
	mdev->dev = dev;

	return mdev;
}

static int mctp_fill_link_af(struct sk_buff *skb,
			     const struct net_device *dev, u32 ext_filter_mask)
{
	struct mctp_dev *mdev;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return -ENODATA;
	if (nla_put_u32(skb, IFLA_MCTP_NET, mdev->net))
		return -EMSGSIZE;
	if (nla_put_u8(skb, IFLA_MCTP_PHYS_BINDING, mdev->binding))
		return -EMSGSIZE;
	return 0;
}

static size_t mctp_get_link_af_size(const struct net_device *dev,
				    u32 ext_filter_mask)
{
	struct mctp_dev *mdev;
	unsigned int ret;

	/* caller holds RCU */
	mdev = __mctp_dev_get(dev);
	if (!mdev)
		return 0;
	ret = nla_total_size(4); /* IFLA_MCTP_NET */
	ret += nla_total_size(1); /* IFLA_MCTP_PHYS_BINDING */
	mctp_dev_put(mdev);
	return ret;
}

static const struct nla_policy ifla_af_mctp_policy[IFLA_MCTP_MAX + 1] = {
	[IFLA_MCTP_NET]		= { .type = NLA_U32 },
};

static int mctp_set_link_af(struct net_device *dev, const struct nlattr *attr,
			    struct netlink_ext_ack *extack)
{
	struct nlattr *tb[IFLA_MCTP_MAX + 1];
	struct mctp_dev *mdev;
	int rc;

	rc = nla_parse_nested(tb, IFLA_MCTP_MAX, attr, ifla_af_mctp_policy,
			      NULL);
	if (rc)
		return rc;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return 0;

	if (tb[IFLA_MCTP_NET])
		WRITE_ONCE(mdev->net, nla_get_u32(tb[IFLA_MCTP_NET]));

	return 0;
}

/* Matches netdev types that should have MCTP handling */
static bool mctp_known(struct net_device *dev)
{
	/* only register specific types (inc. NONE for TUN devices) */
	return dev->type == ARPHRD_MCTP ||
		   dev->type == ARPHRD_LOOPBACK ||
		   dev->type == ARPHRD_NONE;
}

static void mctp_unregister(struct net_device *dev)
{
	struct mctp_dev *mdev;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return;

	RCU_INIT_POINTER(mdev->dev->mctp_ptr, NULL);

	mctp_route_remove_dev(mdev);
	mctp_neigh_remove_dev(mdev);

	mctp_dev_put(mdev);
}

static int mctp_register(struct net_device *dev)
{
	struct mctp_dev *mdev;

	/* Already registered? */
	if (rtnl_dereference(dev->mctp_ptr))
		return 0;

	/* only register specific types */
	if (!mctp_known(dev))
		return 0;

	mdev = mctp_add_dev(dev);
	if (IS_ERR(mdev))
		return PTR_ERR(mdev);

	return 0;
}

static int mctp_dev_notify(struct notifier_block *this, unsigned long event,
			   void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	int rc;

	switch (event) {
	case NETDEV_REGISTER:
		rc = mctp_register(dev);
		if (rc)
			return notifier_from_errno(rc);
		break;
	case NETDEV_UNREGISTER:
		mctp_unregister(dev);
		break;
	}

	return NOTIFY_OK;
}

static int mctp_register_netdevice(struct net_device *dev,
				   const struct mctp_netdev_ops *ops,
				   enum mctp_phys_binding binding)
{
	struct mctp_dev *mdev;

	mdev = mctp_add_dev(dev);
	if (IS_ERR(mdev))
		return PTR_ERR(mdev);

	mdev->ops = ops;
	mdev->binding = binding;

	return register_netdevice(dev);
}

int mctp_register_netdev(struct net_device *dev,
			 const struct mctp_netdev_ops *ops,
			 enum mctp_phys_binding binding)
{
	int rc;

	rtnl_lock();
	rc = mctp_register_netdevice(dev, ops, binding);
	rtnl_unlock();

	return rc;
}
EXPORT_SYMBOL_GPL(mctp_register_netdev);

void mctp_unregister_netdev(struct net_device *dev)
{
	unregister_netdev(dev);
}
EXPORT_SYMBOL_GPL(mctp_unregister_netdev);

static struct rtnl_af_ops mctp_af_ops = {
	.family = AF_MCTP,
	.fill_link_af = mctp_fill_link_af,
	.get_link_af_size = mctp_get_link_af_size,
	.set_link_af = mctp_set_link_af,
};

static struct notifier_block mctp_dev_nb = {
	.notifier_call = mctp_dev_notify,
	.priority = ADDRCONF_NOTIFY_PRIORITY,
};

static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = {
	{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_NEWADDR,
	 .doit = mctp_rtm_newaddr},
	{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_DELADDR,
	 .doit = mctp_rtm_deladdr},
	{.owner = THIS_MODULE, .protocol = PF_MCTP, .msgtype = RTM_GETADDR,
	 .dumpit = mctp_dump_addrinfo},
};

int __init mctp_device_init(void)
{
	int err;

	register_netdevice_notifier(&mctp_dev_nb);

	err = rtnl_af_register(&mctp_af_ops);
	if (err)
		goto err_notifier;

	err = rtnl_register_many(mctp_device_rtnl_msg_handlers);
	if (err)
		goto err_af;

	return 0;
err_af:
	rtnl_af_unregister(&mctp_af_ops);
err_notifier:
	unregister_netdevice_notifier(&mctp_dev_nb);
	return err;
}

void __exit mctp_device_exit(void)
{
	rtnl_unregister_many(mctp_device_rtnl_msg_handlers);
	rtnl_af_unregister(&mctp_af_ops);
	unregister_netdevice_notifier(&mctp_dev_nb);
}
