]> xenbits.xensource.com Git - people/aperard/linux.git/commitdiff
mptcp: implement mptcp_userspace_pm_get_addr
authorGeliang Tang <tanggeliang@kylinos.cn>
Fri, 1 Mar 2024 18:18:36 +0000 (19:18 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Mar 2024 13:07:46 +0000 (13:07 +0000)
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: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/pm_userspace.c
net/mptcp/protocol.h

index 20cbcb62cd8c5ba549f017c58b1e523e9044085a..b9809d988693b9067dd9d32aced9ad1242be93a5 100644 (file)
@@ -638,3 +638,77 @@ out:
        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;
+}
index f23ca7645e96f0e39ae53c728dc7759071c28a47..f848e0203e8897aea87d8f972fdd54098a65d041 100644 (file)
@@ -1069,6 +1069,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)
 {