mptcp: userspace pm send RM_ADDR for ID 0
authorGeliang Tang <geliang.tang@suse.com>
Wed, 25 Oct 2023 23:37:04 +0000 (16:37 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 27 Oct 2023 15:47:17 +0000 (08:47 -0700)
This patch adds the ability to send RM_ADDR for local ID 0. Check
whether id 0 address is removed, if not, put id 0 into a removing
list, pass it to mptcp_pm_remove_addr() to remove id 0 address.

There is no reason not to allow the userspace to remove the initial
address (ID 0). This special case was not taken into account not
letting the userspace to delete all addresses as announced.

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/379
Reviewed-by: Matthieu Baerts <matttbe@kernel.org>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
Signed-off-by: Mat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20231025-send-net-next-20231025-v1-3-db8f25f798eb@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/pm_userspace.c

index 0f92e5b13a8a25611d4715b5b6ba3165505e3a43..25fa37ac3620a073b405f7f92e57f27ec03d91ba 100644 (file)
@@ -208,6 +208,40 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
+                                                    struct genl_info *info)
+{
+       struct mptcp_rm_list list = { .nr = 0 };
+       struct mptcp_subflow_context *subflow;
+       struct sock *sk = (struct sock *)msk;
+       bool has_id_0 = false;
+       int err = -EINVAL;
+
+       lock_sock(sk);
+       mptcp_for_each_subflow(msk, subflow) {
+               if (subflow->local_id == 0) {
+                       has_id_0 = true;
+                       break;
+               }
+       }
+       if (!has_id_0) {
+               GENL_SET_ERR_MSG(info, "address with id 0 not found");
+               goto remove_err;
+       }
+
+       list.ids[list.nr++] = 0;
+
+       spin_lock_bh(&msk->pm.lock);
+       mptcp_pm_remove_addr(msk, &list);
+       spin_unlock_bh(&msk->pm.lock);
+
+       err = 0;
+
+remove_err:
+       release_sock(sk);
+       return err;
+}
+
 int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 {
        struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
@@ -239,6 +273,11 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
                goto remove_err;
        }
 
+       if (id_val == 0) {
+               err = mptcp_userspace_pm_remove_id_zero_address(msk, info);
+               goto remove_err;
+       }
+
        lock_sock((struct sock *)msk);
 
        list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {