mirror of https://gitee.com/openkylin/linux.git
mptcp: more DATA FIN fixes
Currently data fin on data packet are not handled properly: the 'rcv_data_fin_seq' field is interpreted as the last sequence number carrying a valid data, but for data fin packet with valid maps we currently store map_seq + map_len, that is, the next value. The 'write_seq' fields carries instead the value subseguent to the last valid byte, so in mptcp_write_data_fin() we never detect correctly the last DSS map. Fixes:7279da6145
("mptcp: Use MPTCP-level flag for sending DATA_FIN") Fixes:1a49b2c2a5
("mptcp: Handle incoming 32-bit DATA_FIN values") Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c88c5ed75f
commit
017512a07e
|
@ -451,7 +451,10 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
|
|||
static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
|
||||
struct sk_buff *skb, struct mptcp_ext *ext)
|
||||
{
|
||||
u64 data_fin_tx_seq = READ_ONCE(mptcp_sk(subflow->conn)->write_seq);
|
||||
/* The write_seq value has already been incremented, so the actual
|
||||
* sequence number for the DATA_FIN is one less.
|
||||
*/
|
||||
u64 data_fin_tx_seq = READ_ONCE(mptcp_sk(subflow->conn)->write_seq) - 1;
|
||||
|
||||
if (!ext->use_map || !skb->len) {
|
||||
/* RFC6824 requires a DSS mapping with specific values
|
||||
|
@ -460,10 +463,7 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
|
|||
ext->data_fin = 1;
|
||||
ext->use_map = 1;
|
||||
ext->dsn64 = 1;
|
||||
/* The write_seq value has already been incremented, so
|
||||
* the actual sequence number for the DATA_FIN is one less.
|
||||
*/
|
||||
ext->data_seq = data_fin_tx_seq - 1;
|
||||
ext->data_seq = data_fin_tx_seq;
|
||||
ext->subflow_seq = 0;
|
||||
ext->data_len = 1;
|
||||
} else if (ext->data_seq + ext->data_len == data_fin_tx_seq) {
|
||||
|
|
|
@ -749,7 +749,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
|
|||
return MAPPING_DATA_FIN;
|
||||
}
|
||||
} else {
|
||||
u64 data_fin_seq = mpext->data_seq + data_len;
|
||||
u64 data_fin_seq = mpext->data_seq + data_len - 1;
|
||||
|
||||
/* If mpext->data_seq is a 32-bit value, data_fin_seq
|
||||
* must also be limited to 32 bits.
|
||||
|
|
Loading…
Reference in New Issue