@@ -451,17 +451,22 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
451
451
static void mptcp_write_data_fin (struct mptcp_subflow_context * subflow ,
452
452
struct sk_buff * skb , struct mptcp_ext * ext )
453
453
{
454
+ u64 data_fin_tx_seq = READ_ONCE (mptcp_sk (subflow -> conn )-> write_seq );
455
+
454
456
if (!ext -> use_map || !skb -> len ) {
455
457
/* RFC6824 requires a DSS mapping with specific values
456
458
* if DATA_FIN is set but no data payload is mapped
457
459
*/
458
460
ext -> data_fin = 1 ;
459
461
ext -> use_map = 1 ;
460
462
ext -> dsn64 = 1 ;
461
- ext -> data_seq = subflow -> data_fin_tx_seq ;
463
+ /* The write_seq value has already been incremented, so
464
+ * the actual sequence number for the DATA_FIN is one less.
465
+ */
466
+ ext -> data_seq = data_fin_tx_seq - 1 ;
462
467
ext -> subflow_seq = 0 ;
463
468
ext -> data_len = 1 ;
464
- } else if (ext -> data_seq + ext -> data_len == subflow -> data_fin_tx_seq ) {
469
+ } else if (ext -> data_seq + ext -> data_len == data_fin_tx_seq ) {
465
470
/* If there's an existing DSS mapping and it is the
466
471
* final mapping, DATA_FIN consumes 1 additional byte of
467
472
* mapping space.
@@ -477,15 +482,17 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
477
482
struct mptcp_out_options * opts )
478
483
{
479
484
struct mptcp_subflow_context * subflow = mptcp_subflow_ctx (sk );
485
+ struct mptcp_sock * msk = mptcp_sk (subflow -> conn );
480
486
unsigned int dss_size = 0 ;
487
+ u64 snd_data_fin_enable ;
481
488
struct mptcp_ext * mpext ;
482
- struct mptcp_sock * msk ;
483
489
unsigned int ack_size ;
484
490
bool ret = false;
485
491
486
492
mpext = skb ? mptcp_get_ext (skb ) : NULL ;
493
+ snd_data_fin_enable = READ_ONCE (msk -> snd_data_fin_enable );
487
494
488
- if (!skb || (mpext && mpext -> use_map ) || subflow -> data_fin_tx_enable ) {
495
+ if (!skb || (mpext && mpext -> use_map ) || snd_data_fin_enable ) {
489
496
unsigned int map_size ;
490
497
491
498
map_size = TCPOLEN_MPTCP_DSS_BASE + TCPOLEN_MPTCP_DSS_MAP64 ;
@@ -495,7 +502,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
495
502
if (mpext )
496
503
opts -> ext_copy = * mpext ;
497
504
498
- if (skb && subflow -> data_fin_tx_enable )
505
+ if (skb && snd_data_fin_enable )
499
506
mptcp_write_data_fin (subflow , skb , & opts -> ext_copy );
500
507
ret = true;
501
508
}
@@ -504,7 +511,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
504
511
* if the first subflow may have the already the remote key handy
505
512
*/
506
513
opts -> ext_copy .use_ack = 0 ;
507
- msk = mptcp_sk (subflow -> conn );
508
514
if (!READ_ONCE (msk -> can_ack )) {
509
515
* size = ALIGN (dss_size , 4 );
510
516
return ret ;
0 commit comments