Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[sfrench/cifs-2.6.git] / net / mptcp / options.c
index a05270996613c32f801a1d544953850d6db4ff1a..b5850afea3430066f251286d6833bcdfdefa401e 100644 (file)
@@ -942,19 +942,20 @@ reset:
        return false;
 }
 
-static u64 expand_ack(u64 old_ack, u64 cur_ack, bool use_64bit)
+u64 __mptcp_expand_seq(u64 old_seq, u64 cur_seq)
 {
-       u32 old_ack32, cur_ack32;
-
-       if (use_64bit)
-               return cur_ack;
-
-       old_ack32 = (u32)old_ack;
-       cur_ack32 = (u32)cur_ack;
-       cur_ack = (old_ack & GENMASK_ULL(63, 32)) + cur_ack32;
-       if (unlikely(before(cur_ack32, old_ack32)))
-               return cur_ack + (1LL << 32);
-       return cur_ack;
+       u32 old_seq32, cur_seq32;
+
+       old_seq32 = (u32)old_seq;
+       cur_seq32 = (u32)cur_seq;
+       cur_seq = (old_seq & GENMASK_ULL(63, 32)) + cur_seq32;
+       if (unlikely(cur_seq32 < old_seq32 && before(old_seq32, cur_seq32)))
+               return cur_seq + (1LL << 32);
+
+       /* reverse wrap could happen, too */
+       if (unlikely(cur_seq32 > old_seq32 && after(old_seq32, cur_seq32)))
+               return cur_seq - (1LL << 32);
+       return cur_seq;
 }
 
 static void ack_update_msk(struct mptcp_sock *msk,
@@ -972,7 +973,7 @@ static void ack_update_msk(struct mptcp_sock *msk,
         * more dangerous than missing an ack
         */
        old_snd_una = msk->snd_una;
-       new_snd_una = expand_ack(old_snd_una, mp_opt->data_ack, mp_opt->ack64);
+       new_snd_una = mptcp_expand_seq(old_snd_una, mp_opt->data_ack, mp_opt->ack64);
 
        /* ACK for data not even sent yet? Ignore. */
        if (after64(new_snd_una, snd_nxt))
@@ -1009,7 +1010,7 @@ bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool us
                return false;
 
        WRITE_ONCE(msk->rcv_data_fin_seq,
-                  expand_ack(READ_ONCE(msk->ack_seq), data_fin_seq, use_64bit));
+                  mptcp_expand_seq(READ_ONCE(msk->ack_seq), data_fin_seq, use_64bit));
        WRITE_ONCE(msk->rcv_data_fin, 1);
 
        return true;