mptcp: add subflow unique id
authorPaolo Abeni <pabeni@redhat.com>
Tue, 20 Jun 2023 16:30:17 +0000 (18:30 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 22 Jun 2023 05:45:57 +0000 (22:45 -0700)
The user-space need to properly account the data received/sent by
individual subflows. When additional subflows are created and/or
closed during the MPTCP socket lifetime, the information currently
exposed via MPTCP_TCPINFO are not enough: subflows are identified only
by the sequential position inside the info dumps, and that will change
with the above mentioned events.

To solve the above problem, this patch introduces a new subflow
identifier that is unique inside the given MPTCP socket scope.

The initial subflow get the id 1 and the other subflows get incremental
values at join time.

Link: https://github.com/multipath-tcp/mptcp_net-next/issues/388
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c

index d5b8e48..4ebd6e9 100644 (file)
@@ -96,6 +96,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
        list_add(&subflow->node, &msk->conn_list);
        sock_hold(ssock->sk);
        subflow->request_mptcp = 1;
+       subflow->subflow_id = msk->subflow_id++;
 
        /* This is the first subflow, always with id 0 */
        subflow->local_id_valid = 1;
@@ -847,6 +848,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
        if (sk->sk_socket && !ssk->sk_socket)
                mptcp_sock_graft(ssk, sk->sk_socket);
 
+       mptcp_subflow_ctx(ssk)->subflow_id = msk->subflow_id++;
        mptcp_sockopt_sync_locked(msk, ssk);
        mptcp_subflow_joined(msk, ssk);
        return true;
@@ -2732,6 +2734,7 @@ static int __mptcp_init_sock(struct sock *sk)
        WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
        WRITE_ONCE(msk->allow_infinite_fallback, true);
        msk->recovery = false;
+       msk->subflow_id = 1;
 
        mptcp_pm_data_init(msk);
 
@@ -3160,6 +3163,9 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
        msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
        msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
 
+       /* passive msk is created after the first/MPC subflow */
+       msk->subflow_id = 2;
+
        sock_reset_flag(nsk, SOCK_RCU_FREE);
        security_inet_csk_clone(nsk, req);
 
index 27adfcc..bb4cacd 100644 (file)
@@ -323,7 +323,8 @@ struct mptcp_sock {
                u64     rtt_us; /* last maximum rtt of subflows */
        } rcvq_space;
 
-       u32 setsockopt_seq;
+       u32             subflow_id;
+       u32             setsockopt_seq;
        char            ca_name[TCP_CA_NAME_MAX];
        struct mptcp_sock       *dl_next;
 };
@@ -504,6 +505,8 @@ struct mptcp_subflow_context {
        u8      reset_reason:4;
        u8      stale_count;
 
+       u32     subflow_id;
+
        long    delegated_status;
        unsigned long   fail_tout;
 
index 4688daa..222dfcd 100644 (file)
@@ -819,6 +819,7 @@ create_child:
                        if (!ctx->conn)
                                goto fallback;
 
+                       ctx->subflow_id = 1;
                        owner = mptcp_sk(ctx->conn);
                        mptcp_pm_new_connection(owner, child, 1);
 
@@ -1574,6 +1575,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
        subflow->remote_id = remote_id;
        subflow->request_join = 1;
        subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+       subflow->subflow_id = msk->subflow_id++;
        mptcp_info2sockaddr(remote, &addr, ssk->sk_family);
 
        sock_hold(ssk);