]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: mptcp: make DACK4/DACK8 usage consistent among all subflows
authorDavide Caratti <dcaratti@redhat.com>
Tue, 6 Oct 2020 16:26:17 +0000 (18:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:10:51 +0000 (10:10 +0100)
[ Upstream commit 37198e93ced70733f0b993dff28b7c33857e254f ]

using packetdrill it's possible to observe the same MPTCP DSN being acked
by different subflows with DACK4 and DACK8. This is in contrast with what
specified in RFC8684 ยง3.3.2: if an MPTCP endpoint transmits a 64-bit wide
DSN, it MUST be acknowledged with a 64-bit wide DACK. Fix 'use_64bit_ack'
variable to make it a property of MPTCP sockets, not TCP subflows.

Fixes: a0c1d0eafd1e ("mptcp: Use 32-bit DATA_ACK when possible")
Acked-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mptcp/options.c
net/mptcp/protocol.h
net/mptcp/subflow.c

index 277f12633fc93a0b27070f6f7a9cf7a09bfaba8e..b2f018d32840ce604427b824f217123d2ac4fdc4 100644 (file)
@@ -516,7 +516,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
                return ret;
        }
 
-       if (subflow->use_64bit_ack) {
+       if (READ_ONCE(msk->use_64bit_ack)) {
                ack_size = TCPOLEN_MPTCP_DSS_ACK64;
                opts->ext_copy.data_ack = READ_ONCE(msk->ack_seq);
                opts->ext_copy.ack64 = 1;
index 0c4b8cc64dbc0c48bca265b9e5d908f070dbc308..9724636426905a097b27574f604014d80b595731 100644 (file)
@@ -203,6 +203,7 @@ struct mptcp_sock {
        bool            fully_established;
        bool            rcv_data_fin;
        bool            snd_data_fin_enable;
+       bool            use_64bit_ack; /* Set when we received a 64-bit DSN */
        spinlock_t      join_list_lock;
        struct work_struct work;
        struct list_head conn_list;
@@ -295,7 +296,6 @@ struct mptcp_subflow_context {
                backup : 1,
                data_avail : 1,
                rx_eof : 1,
-               use_64bit_ack : 1, /* Set when we received a 64-bit DSN */
                can_ack : 1;        /* only after processing the remote a key */
        u32     remote_nonce;
        u64     thmac;
index 80f67cb56631c7bf6e7de9727ea3bce7d95f710e..559f5bbd962295b83bc8ec0e71dd3f3bd84bd5f7 100644 (file)
@@ -781,12 +781,11 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
        if (!mpext->dsn64) {
                map_seq = expand_seq(subflow->map_seq, subflow->map_data_len,
                                     mpext->data_seq);
-               subflow->use_64bit_ack = 0;
                pr_debug("expanded seq=%llu", subflow->map_seq);
        } else {
                map_seq = mpext->data_seq;
-               subflow->use_64bit_ack = 1;
        }
+       WRITE_ONCE(mptcp_sk(subflow->conn)->use_64bit_ack, !!mpext->dsn64);
 
        if (subflow->map_valid) {
                /* Allow replacing only with an identical map */