Merge branch 'mptcp-sdeq-fixes'
Mat Martineau says: ==================== mptcp: 32-bit sequence number improvements MPTCP-level sequence numbers are 64 bits, but RFC 8684 allows use of 32-bit sequence numbers in the DSS option to save header space. Those 32-bit numbers are the least significant bits of the full 64-bit sequence number, so the receiver must infer the correct upper 32 bits. These two patches improve the logic for determining the full 64-bit sequence numbers when the 32-bit truncated version has wrapped around. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0d0f2a36e3
@ -896,19 +896,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;
|
||||
u32 old_seq32, cur_seq32;
|
||||
|
||||
if (use_64bit)
|
||||
return cur_ack;
|
||||
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);
|
||||
|
||||
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;
|
||||
/* 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,
|
||||
@ -926,7 +927,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))
|
||||
@ -963,7 +964,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;
|
||||
|
@ -593,6 +593,14 @@ int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
||||
int mptcp_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *option);
|
||||
|
||||
u64 __mptcp_expand_seq(u64 old_seq, u64 cur_seq);
|
||||
static inline u64 mptcp_expand_seq(u64 old_seq, u64 cur_seq, bool use_64bit)
|
||||
{
|
||||
if (use_64bit)
|
||||
return cur_seq;
|
||||
|
||||
return __mptcp_expand_seq(old_seq, cur_seq);
|
||||
}
|
||||
void __mptcp_check_push(struct sock *sk, struct sock *ssk);
|
||||
void __mptcp_data_acked(struct sock *sk);
|
||||
void __mptcp_error_report(struct sock *sk);
|
||||
|
@ -775,15 +775,6 @@ enum mapping_status {
|
||||
MAPPING_DUMMY
|
||||
};
|
||||
|
||||
static u64 expand_seq(u64 old_seq, u16 old_data_len, u64 seq)
|
||||
{
|
||||
if ((u32)seq == (u32)old_seq)
|
||||
return old_seq;
|
||||
|
||||
/* Assume map covers data not mapped yet. */
|
||||
return seq | ((old_seq + old_data_len + 1) & GENMASK_ULL(63, 32));
|
||||
}
|
||||
|
||||
static void dbg_bad_map(struct mptcp_subflow_context *subflow, u32 ssn)
|
||||
{
|
||||
pr_debug("Bad mapping: ssn=%d map_seq=%d map_data_len=%d",
|
||||
@ -907,13 +898,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
|
||||
data_len--;
|
||||
}
|
||||
|
||||
if (!mpext->dsn64) {
|
||||
map_seq = expand_seq(subflow->map_seq, subflow->map_data_len,
|
||||
mpext->data_seq);
|
||||
pr_debug("expanded seq=%llu", subflow->map_seq);
|
||||
} else {
|
||||
map_seq = mpext->data_seq;
|
||||
}
|
||||
map_seq = mptcp_expand_seq(READ_ONCE(msk->ack_seq), mpext->data_seq, mpext->dsn64);
|
||||
WRITE_ONCE(mptcp_sk(subflow->conn)->use_64bit_ack, !!mpext->dsn64);
|
||||
|
||||
if (subflow->map_valid) {
|
||||
|
Loading…
Reference in New Issue
Block a user