]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
mptcp: implement mptcp_pm_remove_subflow
authorGeliang Tang <geliangtang@gmail.com>
Thu, 24 Sep 2020 00:29:55 +0000 (08:29 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 25 Sep 2020 02:58:34 +0000 (19:58 -0700)
This patch implemented the local subflow removing function,
mptcp_pm_remove_subflow, it simply called mptcp_pm_nl_rm_subflow_received
under the PM spin lock.

We use mptcp_pm_remove_subflow to remove a local subflow, so change it's
argument from remote_id to local_id.

We check subflow->local_id in mptcp_pm_nl_rm_subflow_received to remove
a subflow.

Suggested-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Suggested-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/pm.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.h

index f450bf0d49aa01ac354821b4c044ea90bcad87af..7e81f53d1e5d2cfa31c1c1cd0fbca4d8d5247b95 100644 (file)
@@ -33,9 +33,14 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id)
        return 0;
 }
 
-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id)
+int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id)
 {
-       return -ENOTSUPP;
+       pr_debug("msk=%p, local_id=%d", msk, local_id);
+
+       spin_lock_bh(&msk->pm.lock);
+       mptcp_pm_nl_rm_subflow_received(msk, local_id);
+       spin_unlock_bh(&msk->pm.lock);
+       return 0;
 }
 
 /* path manager event handlers */
index 97f9280f83fb63b5c5d1357a45a03b88ab5d48b8..9064c809852124f82a116a8ac7f50cc277ccaec0 100644 (file)
@@ -350,6 +350,39 @@ void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
        }
 }
 
+void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id)
+{
+       struct mptcp_subflow_context *subflow, *tmp;
+       struct sock *sk = (struct sock *)msk;
+
+       pr_debug("subflow rm_id %d", rm_id);
+
+       if (!rm_id)
+               return;
+
+       if (list_empty(&msk->conn_list))
+               return;
+
+       list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
+               struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+               int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
+               long timeout = 0;
+
+               if (rm_id != subflow->local_id)
+                       continue;
+
+               spin_unlock_bh(&msk->pm.lock);
+               mptcp_subflow_shutdown(sk, ssk, how);
+               __mptcp_close_ssk(sk, ssk, subflow, timeout);
+               spin_lock_bh(&msk->pm.lock);
+
+               msk->pm.local_addr_used--;
+               msk->pm.subflows--;
+
+               break;
+       }
+}
+
 static bool address_use_port(struct mptcp_pm_addr_entry *entry)
 {
        return (entry->addr.flags &
index d1b1416797f8f3f837fb1bf284cbc750443c1e62..df6cc94df1f74c56be448848eff572f5a2f65d47 100644 (file)
@@ -448,7 +448,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
                           const struct mptcp_addr_info *addr,
                           bool echo);
 int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id);
-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id);
+int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id);
 
 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
 {
@@ -479,6 +479,7 @@ void mptcp_pm_nl_fully_established(struct mptcp_sock *msk);
 void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk);
 void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk);
 void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk);
+void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id);
 int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 
 static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)