mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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
2 changed files with 6 additions and 6 deletions
|
@ -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,
|
static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
|
||||||
struct sk_buff *skb, struct mptcp_ext *ext)
|
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) {
|
if (!ext->use_map || !skb->len) {
|
||||||
/* RFC6824 requires a DSS mapping with specific values
|
/* 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->data_fin = 1;
|
||||||
ext->use_map = 1;
|
ext->use_map = 1;
|
||||||
ext->dsn64 = 1;
|
ext->dsn64 = 1;
|
||||||
/* The write_seq value has already been incremented, so
|
ext->data_seq = data_fin_tx_seq;
|
||||||
* the actual sequence number for the DATA_FIN is one less.
|
|
||||||
*/
|
|
||||||
ext->data_seq = data_fin_tx_seq - 1;
|
|
||||||
ext->subflow_seq = 0;
|
ext->subflow_seq = 0;
|
||||||
ext->data_len = 1;
|
ext->data_len = 1;
|
||||||
} else if (ext->data_seq + ext->data_len == data_fin_tx_seq) {
|
} 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;
|
return MAPPING_DATA_FIN;
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
/* If mpext->data_seq is a 32-bit value, data_fin_seq
|
||||||
* must also be limited to 32 bits.
|
* must also be limited to 32 bits.
|
||||||
|
|
Loading…
Add table
Reference in a new issue