mptcp: add the incoming RM_ADDR support
authorGeliang Tang <geliangtang@gmail.com>
Thu, 24 Sep 2020 00:29:49 +0000 (08:29 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 25 Sep 2020 02:58:33 +0000 (19:58 -0700)
This patch added the RM_ADDR option parsing logic:

We parsed the incoming options to find if the rm_addr option is received,
and called mptcp_pm_rm_addr_received to schedule PM work to a new status,
named MPTCP_PM_RM_ADDR_RECEIVED.

PM work got this status, and called mptcp_pm_nl_rm_addr_received to handle
it.

In mptcp_pm_nl_rm_addr_received, we closed the subflow matching the rm_id,
and updated PM counter.

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/options.c
net/mptcp/pm.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/protocol.h

index bbc1248..a52a05e 100644 (file)
@@ -888,6 +888,11 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
                mp_opt.add_addr = 0;
        }
 
+       if (mp_opt.rm_addr) {
+               mptcp_pm_rm_addr_received(msk, mp_opt.rm_id);
+               mp_opt.rm_addr = 0;
+       }
+
        if (!mp_opt.dss)
                return;
 
index 81b07ae..558462d 100644 (file)
@@ -149,6 +149,18 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
        spin_unlock_bh(&pm->lock);
 }
 
+void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
+{
+       struct mptcp_pm_data *pm = &msk->pm;
+
+       pr_debug("msk=%p remote_id=%d", msk, rm_id);
+
+       spin_lock_bh(&pm->lock);
+       mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
+       pm->rm_id = rm_id;
+       spin_unlock_bh(&pm->lock);
+}
+
 /* path manager helpers */
 
 bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
index b4a9624..4124bc5 100644 (file)
@@ -268,6 +268,40 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
        spin_lock_bh(&msk->pm.lock);
 }
 
+void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
+{
+       struct mptcp_subflow_context *subflow, *tmp;
+       struct sock *sk = (struct sock *)msk;
+
+       pr_debug("address rm_id %d", msk->pm.rm_id);
+
+       if (!msk->pm.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 (msk->pm.rm_id != subflow->remote_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.add_addr_accepted--;
+               msk->pm.subflows--;
+               WRITE_ONCE(msk->pm.accept_addr, true);
+
+               break;
+       }
+}
+
 static bool address_use_port(struct mptcp_pm_addr_entry *entry)
 {
        return (entry->addr.flags &
index 386cd4e..26b9233 100644 (file)
@@ -1652,9 +1652,9 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
  * so we need to use tcp_close() after detaching them from the mptcp
  * parent socket.
  */
-static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
-                             struct mptcp_subflow_context *subflow,
-                             long timeout)
+void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+                      struct mptcp_subflow_context *subflow,
+                      long timeout)
 {
        struct socket *sock = READ_ONCE(ssk->sk_socket);
 
@@ -1685,6 +1685,10 @@ static void pm_work(struct mptcp_sock *msk)
                pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
                mptcp_pm_nl_add_addr_received(msk);
        }
+       if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) {
+               pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED);
+               mptcp_pm_nl_rm_addr_received(msk);
+       }
        if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
                pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
                mptcp_pm_nl_fully_established(msk);
@@ -1846,7 +1850,7 @@ static void mptcp_cancel_work(struct sock *sk)
                sock_put(sk);
 }
 
-static void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
+void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
 {
        lock_sock(ssk);
 
index 8929b0c..837e010 100644 (file)
@@ -152,6 +152,7 @@ struct mptcp_addr_info {
 
 enum mptcp_pm_status {
        MPTCP_PM_ADD_ADDR_RECEIVED,
+       MPTCP_PM_RM_ADDR_RECEIVED,
        MPTCP_PM_ESTABLISHED,
        MPTCP_PM_SUBFLOW_ESTABLISHED,
 };
@@ -362,6 +363,10 @@ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
                                     struct mptcp_options_received *mp_opt);
 bool mptcp_subflow_data_available(struct sock *sk);
 void __init mptcp_subflow_init(void);
+void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
+void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+                      struct mptcp_subflow_context *subflow,
+                      long timeout);
 
 /* called with sk socket lock held */
 int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
@@ -434,6 +439,7 @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk,
 void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id);
 void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
                                const struct mptcp_addr_info *addr);
+void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
 
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
                           const struct mptcp_addr_info *addr);
@@ -468,6 +474,7 @@ void mptcp_pm_nl_data_init(struct mptcp_sock *msk);
 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);
 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)