Commit 06abc2ff authored by Geliang Tang's avatar Geliang Tang
Browse files

mptcp: implement mptcp_userspace_pm_get_addr

mainline inclusion
from mainline-v6.9-rc1
commit d32c8fb1c881478e4af8e6ac3c922d35c8ba3ca8
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9VYQ9
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=d32c8fb1c881478e4af8e6ac3c922d35c8ba3ca8



--------------------------------

This patch implements mptcp_userspace_pm_get_addr() to get an address
from userspace pm address list according the given 'token' and 'id'.
Use nla_get_u32() to get the u32 value of 'token', then pass it to
mptcp_token_get_sock() to get the msk. Pass 'msk' and 'id' to the helper
mptcp_userspace_pm_lookup_addr_by_id() to get the address entry. Put
this entry to userspace using mptcp_pm_nl_put_entry_info().

Signed-off-by: default avatarGeliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Reviewed-by: default avatarJackie Liu <liuyun01@kylinos.cn>
Signed-off-by: default avatarGeliang Tang <tanggeliang@kylinos.cn>
parent 468e8cfe
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -638,3 +638,77 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
	sock_put(sk);
	return ret;
}

int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
				struct genl_info *info)
{
	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
	struct mptcp_pm_addr_entry addr, *entry;
	struct net *net = sock_net(skb->sk);
	struct mptcp_sock *msk;
	struct sk_buff *msg;
	int ret = -EINVAL;
	struct sock *sk;
	void *reply;

	msk = mptcp_token_get_sock(net, nla_get_u32(token));
	if (!msk) {
		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
		return ret;
	}

	sk = (struct sock *)msk;

	if (!mptcp_pm_is_userspace(msk)) {
		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
		goto out;
	}

	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
	if (ret < 0)
		goto out;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto out;
	}

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

	lock_sock(sk);
	spin_lock_bh(&msk->pm.lock);
	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, 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(&msk->pm.lock);
	release_sock(sk);
	sock_put(sk);
	return ret;

unlock_fail:
	spin_unlock_bh(&msk->pm.lock);
	release_sock(sk);
fail:
	nlmsg_free(msg);
out:
	sock_put(sk);
	return ret;
}
+2 −0
Original line number Diff line number Diff line
@@ -1074,6 +1074,8 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
			  struct netlink_callback *cb);
int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
				 struct netlink_callback *cb);
int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
				struct genl_info *info);

static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
{