OSDN Git Service

mptcp: fix per socket endpoint accounting
authorPaolo Abeni <pabeni@redhat.com>
Fri, 7 Jan 2022 00:20:20 +0000 (16:20 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 7 Jan 2022 11:27:07 +0000 (11:27 +0000)
Since full-mesh endpoint support, the reception of a single ADD_ADDR
option can cause multiple subflows creation. When such option is
accepted we increment 'add_addr_accepted' by one. When we received
a paired RM_ADDR option, we deleted all the relevant subflows,
decrementing 'add_addr_accepted' by one for each of them.

We have a similar issue for 'local_addr_used'

Fix them moving the pm endpoint accounting outside the subflow
traversal.

Fixes: 1a0d6136c5f0 ("mptcp: local addresses fullmesh")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/pm_netlink.c

index 6cde58c..27427ae 100644 (file)
@@ -711,6 +711,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
                return;
 
        for (i = 0; i < rm_list->nr; i++) {
+               bool removed = false;
+
                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;
@@ -730,15 +732,19 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
                        mptcp_close_ssk(sk, ssk, subflow);
                        spin_lock_bh(&msk->pm.lock);
 
-                       if (rm_type == MPTCP_MIB_RMADDR) {
-                               msk->pm.add_addr_accepted--;
-                               WRITE_ONCE(msk->pm.accept_addr, true);
-                       } else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
-                               msk->pm.local_addr_used--;
-                       }
+                       removed = true;
                        msk->pm.subflows--;
                        __MPTCP_INC_STATS(sock_net(sk), rm_type);
                }
+               if (!removed)
+                       continue;
+
+               if (rm_type == MPTCP_MIB_RMADDR) {
+                       msk->pm.add_addr_accepted--;
+                       WRITE_ONCE(msk->pm.accept_addr, true);
+               } else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
+                       msk->pm.local_addr_used--;
+               }
        }
 }