// SPDX-License-Identifier: GPL-2.0
/* Multipath TCP
 *
 * Copyright (c) 2020, Red Hat, Inc.
 */

#define pr_fmt(fmt) "MPTCP: " fmt

#include <linux/inet.h>
#include <linux/kernel.h>
#include <net/tcp.h>
#include <net/netns/generic.h>
#include <net/mptcp.h>
#include <net/genetlink.h>
#include <uapi/linux/mptcp.h>

#include "protocol.h"

/* forward declaration */
static struct genl_family mptcp_genl_family;

static int pm_nl_pernet_id;

struct mptcp_pm_addr_entry {
	struct list_head	list;
	unsigned int		flags;
	int			ifindex;
	struct mptcp_addr_info	addr;
	struct rcu_head		rcu;
};

struct pm_nl_pernet {
	/* protects pernet updates */
	spinlock_t		lock;
	struct list_head	local_addr_list;
	unsigned int		addrs;
	unsigned int		add_addr_signal_max;
	unsigned int		add_addr_accept_max;
	unsigned int		local_addr_max;
	unsigned int		subflows_max;
	unsigned int		next_id;
};

#define MPTCP_PM_ADDR_MAX	8

static bool addresses_equal(const struct mptcp_addr_info *a,
			    struct mptcp_addr_info *b, bool use_port)
{
	bool addr_equals = false;

	if (a->family != b->family)
		return false;

	if (a->family == AF_INET)
		addr_equals = a->addr.s_addr == b->addr.s_addr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	else
		addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
#endif

	if (!addr_equals)
		return false;
	if (!use_port)
		return true;

	return a->port == b->port;
}

static void local_address(const struct sock_common *skc,
			  struct mptcp_addr_info *addr)
{
	addr->port = 0;
	addr->family = skc->skc_family;
	if (addr->family == AF_INET)
		addr->addr.s_addr = skc->skc_rcv_saddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	else if (addr->family == AF_INET6)
		addr->addr6 = skc->skc_v6_rcv_saddr;
#endif
}

static void remote_address(const struct sock_common *skc,
			   struct mptcp_addr_info *addr)
{
	addr->family = skc->skc_family;
	addr->port = skc->skc_dport;
	if (addr->family == AF_INET)
		addr->addr.s_addr = skc->skc_daddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	else if (addr->family == AF_INET6)
		addr->addr6 = skc->skc_v6_daddr;
#endif
}

static bool lookup_subflow_by_saddr(const struct list_head *list,
				    struct mptcp_addr_info *saddr)
{
	struct mptcp_subflow_context *subflow;
	struct mptcp_addr_info cur;
	struct sock_common *skc;

	list_for_each_entry(subflow, list, node) {
		skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);

		local_address(skc, &cur);
		if (addresses_equal(&cur, saddr, false))
			return true;
	}

	return false;
}

static struct mptcp_pm_addr_entry *
select_local_address(const struct pm_nl_pernet *pernet,
		     struct mptcp_sock *msk)
{
	struct mptcp_pm_addr_entry *entry, *ret = NULL;

	rcu_read_lock();
	spin_lock_bh(&msk->join_list_lock);
	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
			continue;

		/* avoid any address already in use by subflows and
		 * pending join
		 */
		if (entry->addr.family == ((struct sock *)msk)->sk_family &&
		    !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
		    !lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) {
			ret = entry;
			break;
		}
	}
	spin_unlock_bh(&msk->join_list_lock);
	rcu_read_unlock();
	return ret;
}

static struct mptcp_pm_addr_entry *
select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
{
	struct mptcp_pm_addr_entry *entry, *ret = NULL;
	int i = 0;

	rcu_read_lock();
	/* do not keep any additional per socket state, just signal
	 * the address list in order.
	 * Note: removal from the local address list during the msk life-cycle
	 * can lead to additional addresses not being announced.
	 */
	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
			continue;
		if (i++ == pos) {
			ret = entry;
			break;
		}
	}
	rcu_read_unlock();
	return ret;
}

static void check_work_pending(struct mptcp_sock *msk)
{
	if (msk->pm.add_addr_signaled == msk->pm.add_addr_signal_max &&
	    (msk->pm.local_addr_used == msk->pm.local_addr_max ||
	     msk->pm.subflows == msk->pm.subflows_max))
		WRITE_ONCE(msk->pm.work_pending, false);
}

static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
	struct sock *sk = (struct sock *)msk;
	struct mptcp_pm_addr_entry *local;
	struct mptcp_addr_info remote;
	struct pm_nl_pernet *pernet;

	pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);

	pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
		 msk->pm.local_addr_used, msk->pm.local_addr_max,
		 msk->pm.add_addr_signaled, msk->pm.add_addr_signal_max,
		 msk->pm.subflows, msk->pm.subflows_max);

	/* check first for announce */
	if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) {
		local = select_signal_address(pernet,
					      msk->pm.add_addr_signaled);

		if (local) {
			msk->pm.add_addr_signaled++;
			mptcp_pm_announce_addr(msk, &local->addr);
		} else {
			/* pick failed, avoid fourther attempts later */
			msk->pm.local_addr_used = msk->pm.add_addr_signal_max;
		}

		check_work_pending(msk);
	}

	/* check if should create a new subflow */
	if (msk->pm.local_addr_used < msk->pm.local_addr_max &&
	    msk->pm.subflows < msk->pm.subflows_max) {
		remote_address((struct sock_common *)sk, &remote);

		local = select_local_address(pernet, msk);
		if (local) {
			msk->pm.local_addr_used++;
			msk->pm.subflows++;
			check_work_pending(msk);
			spin_unlock_bh(&msk->pm.lock);
			__mptcp_subflow_connect(sk, local->ifindex,
						&local->addr, &remote);
			spin_lock_bh(&msk->pm.lock);
			return;
		}

		/* lookup failed, avoid fourther attempts later */
		msk->pm.local_addr_used = msk->pm.local_addr_max;
		check_work_pending(msk);
	}
}

void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
{
	mptcp_pm_create_subflow_or_signal_addr(msk);
}

void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
{
	mptcp_pm_create_subflow_or_signal_addr(msk);
}

void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
{
	struct sock *sk = (struct sock *)msk;
	struct mptcp_addr_info remote;
	struct mptcp_addr_info local;

	pr_debug("accepted %d:%d remote family %d",
		 msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max,
		 msk->pm.remote.family);
	msk->pm.add_addr_accepted++;
	msk->pm.subflows++;
	if (msk->pm.add_addr_accepted >= msk->pm.add_addr_accept_max ||
	    msk->pm.subflows >= msk->pm.subflows_max)
		WRITE_ONCE(msk->pm.accept_addr, false);

	/* connect to the specified remote address, using whatever
	 * local address the routing configuration will pick.
	 */
	remote = msk->pm.remote;
	if (!remote.port)
		remote.port = sk->sk_dport;
	memset(&local, 0, sizeof(local));
	local.family = remote.family;

	spin_unlock_bh(&msk->pm.lock);
	__mptcp_subflow_connect((struct sock *)msk, 0, &local, &remote);
	spin_lock_bh(&msk->pm.lock);
}

static bool address_use_port(struct mptcp_pm_addr_entry *entry)
{
	return (entry->flags &
		(MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) ==
		MPTCP_PM_ADDR_FLAG_SIGNAL;
}

static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
					     struct mptcp_pm_addr_entry *entry)
{
	struct mptcp_pm_addr_entry *cur;
	int ret = -EINVAL;

	spin_lock_bh(&pernet->lock);
	/* to keep the code simple, don't do IDR-like allocation for address ID,
	 * just bail when we exceed limits
	 */
	if (pernet->next_id > 255)
		goto out;
	if (pernet->addrs >= MPTCP_PM_ADDR_MAX)
		goto out;

	/* do not insert duplicate address, differentiate on port only
	 * singled addresses
	 */
	list_for_each_entry(cur, &pernet->local_addr_list, list) {
		if (addresses_equal(&cur->addr, &entry->addr,
				    address_use_port(entry) &&
				    address_use_port(cur)))
			goto out;
	}

	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
		pernet->add_addr_signal_max++;
	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
		pernet->local_addr_max++;

	entry->addr.id = pernet->next_id++;
	pernet->addrs++;
	list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
	ret = entry->addr.id;

out:
	spin_unlock_bh(&pernet->lock);
	return ret;
}

int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
{
	struct mptcp_pm_addr_entry *entry;
	struct mptcp_addr_info skc_local;
	struct mptcp_addr_info msk_local;
	struct pm_nl_pernet *pernet;
	int ret = -1;

	if (WARN_ON_ONCE(!msk))
		return -1;

	/* The 0 ID mapping is defined by the first subflow, copied into the msk
	 * addr
	 */
	local_address((struct sock_common *)msk, &msk_local);
	local_address((struct sock_common *)msk, &skc_local);
	if (addresses_equal(&msk_local, &skc_local, false))
		return 0;

	pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);

	rcu_read_lock();
	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
		if (addresses_equal(&entry->addr, &skc_local, false)) {
			ret = entry->addr.id;
			break;
		}
	}
	rcu_read_unlock();
	if (ret >= 0)
		return ret;

	/* address not found, add to local list */
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		return -ENOMEM;

	entry->flags = 0;
	entry->addr = skc_local;
	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
	if (ret < 0)
		kfree(entry);

	return ret;
}

void mptcp_pm_nl_data_init(struct mptcp_sock *msk)
{
	struct mptcp_pm_data *pm = &msk->pm;
	struct pm_nl_pernet *pernet;
	bool subflows;

	pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);

	pm->add_addr_signal_max = READ_ONCE(pernet->add_addr_signal_max);
	pm->add_addr_accept_max = READ_ONCE(pernet->add_addr_accept_max);
	pm->local_addr_max = READ_ONCE(pernet->local_addr_max);
	pm->subflows_max = READ_ONCE(pernet->subflows_max);
	subflows = !!pm->subflows_max;
	WRITE_ONCE(pm->work_pending, (!!pm->local_addr_max && subflows) ||
		   !!pm->add_addr_signal_max);
	WRITE_ONCE(pm->accept_addr, !!pm->add_addr_accept_max && subflows);
	WRITE_ONCE(pm->accept_subflow, subflows);
}

#define MPTCP_PM_CMD_GRP_OFFSET	0

static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
	[MPTCP_PM_CMD_GRP_OFFSET]	= { .name = MPTCP_PM_CMD_GRP_NAME, },
};

static const struct nla_policy
mptcp_pm_addr_policy[MPTCP_PM_ADDR_ATTR_MAX + 1] = {
	[MPTCP_PM_ADDR_ATTR_FAMILY]	= { .type	= NLA_U16,	},
	[MPTCP_PM_ADDR_ATTR_ID]		= { .type	= NLA_U8,	},
	[MPTCP_PM_ADDR_ATTR_ADDR4]	= { .type	= NLA_U32,	},
	[MPTCP_PM_ADDR_ATTR_ADDR6]	= { .type	= NLA_EXACT_LEN,
					    .len   = sizeof(struct in6_addr), },
	[MPTCP_PM_ADDR_ATTR_PORT]	= { .type	= NLA_U16	},
	[MPTCP_PM_ADDR_ATTR_FLAGS]	= { .type	= NLA_U32	},
	[MPTCP_PM_ADDR_ATTR_IF_IDX]     = { .type	= NLA_S32	},
};

static const struct nla_policy mptcp_pm_policy[MPTCP_PM_ATTR_MAX + 1] = {
	[MPTCP_PM_ATTR_ADDR]		=
					NLA_POLICY_NESTED(mptcp_pm_addr_policy),
	[MPTCP_PM_ATTR_RCV_ADD_ADDRS]	= { .type	= NLA_U32,	},
	[MPTCP_PM_ATTR_SUBFLOWS]	= { .type	= NLA_U32,	},
};

static int mptcp_pm_family_to_addr(int family)
{
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	if (family == AF_INET6)
		return MPTCP_PM_ADDR_ATTR_ADDR6;
#endif
	return MPTCP_PM_ADDR_ATTR_ADDR4;
}

static int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
			       bool require_family,
			       struct mptcp_pm_addr_entry *entry)
{
	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
	int err, addr_addr;

	if (!attr) {
		GENL_SET_ERR_MSG(info, "missing address info");
		return -EINVAL;
	}

	/* no validation needed - was already done via nested policy */
	err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
					  mptcp_pm_addr_policy, info->extack);
	if (err)
		return err;

	memset(entry, 0, sizeof(*entry));
	if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
		if (!require_family)
			goto skip_family;

		NL_SET_ERR_MSG_ATTR(info->extack, attr,
				    "missing family");
		return -EINVAL;
	}

	entry->addr.family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
	if (entry->addr.family != AF_INET
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	    && entry->addr.family != AF_INET6
#endif
	    ) {
		NL_SET_ERR_MSG_ATTR(info->extack, attr,
				    "unknown address family");
		return -EINVAL;
	}
	addr_addr = mptcp_pm_family_to_addr(entry->addr.family);
	if (!tb[addr_addr]) {
		NL_SET_ERR_MSG_ATTR(info->extack, attr,
				    "missing address data");
		return -EINVAL;
	}

#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	if (entry->addr.family == AF_INET6)
		entry->addr.addr6 = nla_get_in6_addr(tb[addr_addr]);
	else
#endif
		entry->addr.addr.s_addr = nla_get_in_addr(tb[addr_addr]);

skip_family:
	if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX])
		entry->ifindex = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);

	if (tb[MPTCP_PM_ADDR_ATTR_ID])
		entry->addr.id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);

	if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
		entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);

	return 0;
}

static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
{
	return net_generic(genl_info_net(info), pm_nl_pernet_id);
}

static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
	struct mptcp_pm_addr_entry addr, *entry;
	int ret;

	ret = mptcp_pm_parse_addr(attr, info, true, &addr);
	if (ret < 0)
		return ret;

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry) {
		GENL_SET_ERR_MSG(info, "can't allocate addr");
		return -ENOMEM;
	}

	*entry = addr;
	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
	if (ret < 0) {
		GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
		kfree(entry);
		return ret;
	}

	return 0;
}

static struct mptcp_pm_addr_entry *
__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
{
	struct mptcp_pm_addr_entry *entry;

	list_for_each_entry(entry, &pernet->local_addr_list, list) {
		if (entry->addr.id == id)
			return entry;
	}
	return NULL;
}

static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
	struct mptcp_pm_addr_entry addr, *entry;
	int ret;

	ret = mptcp_pm_parse_addr(attr, info, false, &addr);
	if (ret < 0)
		return ret;

	spin_lock_bh(&pernet->lock);
	entry = __lookup_addr_by_id(pernet, addr.addr.id);
	if (!entry) {
		GENL_SET_ERR_MSG(info, "address not found");
		ret = -EINVAL;
		goto out;
	}
	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
		pernet->add_addr_signal_max--;
	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
		pernet->local_addr_max--;

	pernet->addrs--;
	list_del_rcu(&entry->list);
	kfree_rcu(entry, rcu);
out:
	spin_unlock_bh(&pernet->lock);
	return ret;
}

static void __flush_addrs(struct pm_nl_pernet *pernet)
{
	while (!list_empty(&pernet->local_addr_list)) {
		struct mptcp_pm_addr_entry *cur;

		cur = list_entry(pernet->local_addr_list.next,
				 struct mptcp_pm_addr_entry, list);
		list_del_rcu(&cur->list);
		kfree_rcu(cur, rcu);
	}
}

static void __reset_counters(struct pm_nl_pernet *pernet)
{
	pernet->add_addr_signal_max = 0;
	pernet->add_addr_accept_max = 0;
	pernet->local_addr_max = 0;
	pernet->addrs = 0;
}

static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
{
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);

	spin_lock_bh(&pernet->lock);
	__flush_addrs(pernet);
	__reset_counters(pernet);
	spin_unlock_bh(&pernet->lock);
	return 0;
}

static int mptcp_nl_fill_addr(struct sk_buff *skb,
			      struct mptcp_pm_addr_entry *entry)
{
	struct mptcp_addr_info *addr = &entry->addr;
	struct nlattr *attr;

	attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
	if (!attr)
		return -EMSGSIZE;

	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
		goto nla_put_failure;
	if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
		goto nla_put_failure;
	if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
		goto nla_put_failure;
	if (entry->ifindex &&
	    nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
		goto nla_put_failure;

	if (addr->family == AF_INET &&
	    nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
			    addr->addr.s_addr))
		goto nla_put_failure;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
	else if (addr->family == AF_INET6 &&
		 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
		goto nla_put_failure;
#endif
	nla_nest_end(skb, attr);
	return 0;

nla_put_failure:
	nla_nest_cancel(skb, attr);
	return -EMSGSIZE;
}

static int mptcp_nl_cmd_get_addr(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
	struct mptcp_pm_addr_entry addr, *entry;
	struct sk_buff *msg;
	void *reply;
	int ret;

	ret = mptcp_pm_parse_addr(attr, info, false, &addr);
	if (ret < 0)
		return ret;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
				  info->genlhdr->cmd);
	if (!reply) {
		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
		ret = -EMSGSIZE;
		goto fail;
	}

	spin_lock_bh(&pernet->lock);
	entry = __lookup_addr_by_id(pernet, addr.addr.id);
	if (!entry) {
		GENL_SET_ERR_MSG(info, "address not found");
		ret = -EINVAL;
		goto unlock_fail;
	}

	ret = mptcp_nl_fill_addr(msg, entry);
	if (ret)
		goto unlock_fail;

	genlmsg_end(msg, reply);
	ret = genlmsg_reply(msg, info);
	spin_unlock_bh(&pernet->lock);
	return ret;

unlock_fail:
	spin_unlock_bh(&pernet->lock);

fail:
	nlmsg_free(msg);
	return ret;
}

static int mptcp_nl_cmd_dump_addrs(struct sk_buff *msg,
				   struct netlink_callback *cb)
{
	struct net *net = sock_net(msg->sk);
	struct mptcp_pm_addr_entry *entry;
	struct pm_nl_pernet *pernet;
	int id = cb->args[0];
	void *hdr;

	pernet = net_generic(net, pm_nl_pernet_id);

	spin_lock_bh(&pernet->lock);
	list_for_each_entry(entry, &pernet->local_addr_list, list) {
		if (entry->addr.id <= id)
			continue;

		hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
				  cb->nlh->nlmsg_seq, &mptcp_genl_family,
				  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
		if (!hdr)
			break;

		if (mptcp_nl_fill_addr(msg, entry) < 0) {
			genlmsg_cancel(msg, hdr);
			break;
		}

		id = entry->addr.id;
		genlmsg_end(msg, hdr);
	}
	spin_unlock_bh(&pernet->lock);

	cb->args[0] = id;
	return msg->len;
}

static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
{
	struct nlattr *attr = info->attrs[id];

	if (!attr)
		return 0;

	*limit = nla_get_u32(attr);
	if (*limit > MPTCP_PM_ADDR_MAX) {
		GENL_SET_ERR_MSG(info, "limit greater than maximum");
		return -EINVAL;
	}
	return 0;
}

static int
mptcp_nl_cmd_set_limits(struct sk_buff *skb, struct genl_info *info)
{
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
	unsigned int rcv_addrs, subflows;
	int ret;

	spin_lock_bh(&pernet->lock);
	rcv_addrs = pernet->add_addr_accept_max;
	ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs);
	if (ret)
		goto unlock;

	subflows = pernet->subflows_max;
	ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows);
	if (ret)
		goto unlock;

	WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs);
	WRITE_ONCE(pernet->subflows_max, subflows);

unlock:
	spin_unlock_bh(&pernet->lock);
	return ret;
}

static int
mptcp_nl_cmd_get_limits(struct sk_buff *skb, struct genl_info *info)
{
	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
	struct sk_buff *msg;
	void *reply;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
				  MPTCP_PM_CMD_GET_LIMITS);
	if (!reply)
		goto fail;

	if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
			READ_ONCE(pernet->add_addr_accept_max)))
		goto fail;

	if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS,
			READ_ONCE(pernet->subflows_max)))
		goto fail;

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

fail:
	GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
	nlmsg_free(msg);
	return -EMSGSIZE;
}

static struct genl_ops mptcp_pm_ops[] = {
	{
		.cmd    = MPTCP_PM_CMD_ADD_ADDR,
		.doit   = mptcp_nl_cmd_add_addr,
		.flags  = GENL_ADMIN_PERM,
	},
	{
		.cmd    = MPTCP_PM_CMD_DEL_ADDR,
		.doit   = mptcp_nl_cmd_del_addr,
		.flags  = GENL_ADMIN_PERM,
	},
	{
		.cmd    = MPTCP_PM_CMD_FLUSH_ADDRS,
		.doit   = mptcp_nl_cmd_flush_addrs,
		.flags  = GENL_ADMIN_PERM,
	},
	{
		.cmd    = MPTCP_PM_CMD_GET_ADDR,
		.doit   = mptcp_nl_cmd_get_addr,
		.dumpit   = mptcp_nl_cmd_dump_addrs,
	},
	{
		.cmd    = MPTCP_PM_CMD_SET_LIMITS,
		.doit   = mptcp_nl_cmd_set_limits,
		.flags  = GENL_ADMIN_PERM,
	},
	{
		.cmd    = MPTCP_PM_CMD_GET_LIMITS,
		.doit   = mptcp_nl_cmd_get_limits,
	},
};

static struct genl_family mptcp_genl_family __ro_after_init = {
	.name		= MPTCP_PM_NAME,
	.version	= MPTCP_PM_VER,
	.maxattr	= MPTCP_PM_ATTR_MAX,
	.policy		= mptcp_pm_policy,
	.netnsok	= true,
	.module		= THIS_MODULE,
	.ops		= mptcp_pm_ops,
	.n_ops		= ARRAY_SIZE(mptcp_pm_ops),
	.mcgrps		= mptcp_pm_mcgrps,
	.n_mcgrps	= ARRAY_SIZE(mptcp_pm_mcgrps),
};

static int __net_init pm_nl_init_net(struct net *net)
{
	struct pm_nl_pernet *pernet = net_generic(net, pm_nl_pernet_id);

	INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
	__reset_counters(pernet);
	pernet->next_id = 1;
	spin_lock_init(&pernet->lock);
	return 0;
}

static void __net_exit pm_nl_exit_net(struct list_head *net_list)
{
	struct net *net;

	list_for_each_entry(net, net_list, exit_list) {
		/* net is removed from namespace list, can't race with
		 * other modifiers
		 */
		__flush_addrs(net_generic(net, pm_nl_pernet_id));
	}
}

static struct pernet_operations mptcp_pm_pernet_ops = {
	.init = pm_nl_init_net,
	.exit_batch = pm_nl_exit_net,
	.id = &pm_nl_pernet_id,
	.size = sizeof(struct pm_nl_pernet),
};

void mptcp_pm_nl_init(void)
{
	if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
		panic("Failed to register MPTCP PM pernet subsystem.\n");

	if (genl_register_family(&mptcp_genl_family))
		panic("Failed to register MPTCP PM netlink family\n");
}
