Skip to content

Commit 7279da6

Browse files
mjmartineaudavem330
authored andcommitted
mptcp: Use MPTCP-level flag for sending DATA_FIN
Since DATA_FIN information is the same for every subflow, store it only in the mptcp_sock. Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 242e63f commit 7279da6

File tree

3 files changed

+18
-24
lines changed

3 files changed

+18
-24
lines changed

net/mptcp/options.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -451,17 +451,22 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
451451
static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
452452
struct sk_buff *skb, struct mptcp_ext *ext)
453453
{
454+
u64 data_fin_tx_seq = READ_ONCE(mptcp_sk(subflow->conn)->write_seq);
455+
454456
if (!ext->use_map || !skb->len) {
455457
/* RFC6824 requires a DSS mapping with specific values
456458
* if DATA_FIN is set but no data payload is mapped
457459
*/
458460
ext->data_fin = 1;
459461
ext->use_map = 1;
460462
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;
462467
ext->subflow_seq = 0;
463468
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) {
465470
/* If there's an existing DSS mapping and it is the
466471
* final mapping, DATA_FIN consumes 1 additional byte of
467472
* mapping space.
@@ -477,15 +482,17 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
477482
struct mptcp_out_options *opts)
478483
{
479484
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
485+
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
480486
unsigned int dss_size = 0;
487+
u64 snd_data_fin_enable;
481488
struct mptcp_ext *mpext;
482-
struct mptcp_sock *msk;
483489
unsigned int ack_size;
484490
bool ret = false;
485491

486492
mpext = skb ? mptcp_get_ext(skb) : NULL;
493+
snd_data_fin_enable = READ_ONCE(msk->snd_data_fin_enable);
487494

488-
if (!skb || (mpext && mpext->use_map) || subflow->data_fin_tx_enable) {
495+
if (!skb || (mpext && mpext->use_map) || snd_data_fin_enable) {
489496
unsigned int map_size;
490497

491498
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,
495502
if (mpext)
496503
opts->ext_copy = *mpext;
497504

498-
if (skb && subflow->data_fin_tx_enable)
505+
if (skb && snd_data_fin_enable)
499506
mptcp_write_data_fin(subflow, skb, &opts->ext_copy);
500507
ret = true;
501508
}
@@ -504,7 +511,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
504511
* if the first subflow may have the already the remote key handy
505512
*/
506513
opts->ext_copy.use_ack = 0;
507-
msk = mptcp_sk(subflow->conn);
508514
if (!READ_ONCE(msk->can_ack)) {
509515
*size = ALIGN(dss_size, 4);
510516
return ret;

net/mptcp/protocol.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,7 @@ static void mptcp_cancel_work(struct sock *sk)
13911391
sock_put(sk);
13921392
}
13931393

1394-
static void mptcp_subflow_shutdown(struct sock *ssk, int how,
1395-
bool data_fin_tx_enable, u64 data_fin_tx_seq)
1394+
static void mptcp_subflow_shutdown(struct sock *ssk, int how)
13961395
{
13971396
lock_sock(ssk);
13981397

@@ -1405,14 +1404,6 @@ static void mptcp_subflow_shutdown(struct sock *ssk, int how,
14051404
tcp_disconnect(ssk, O_NONBLOCK);
14061405
break;
14071406
default:
1408-
if (data_fin_tx_enable) {
1409-
struct mptcp_subflow_context *subflow;
1410-
1411-
subflow = mptcp_subflow_ctx(ssk);
1412-
subflow->data_fin_tx_seq = data_fin_tx_seq;
1413-
subflow->data_fin_tx_enable = 1;
1414-
}
1415-
14161407
ssk->sk_shutdown |= how;
14171408
tcp_shutdown(ssk, how);
14181409
break;
@@ -1426,7 +1417,6 @@ static void mptcp_close(struct sock *sk, long timeout)
14261417
struct mptcp_subflow_context *subflow, *tmp;
14271418
struct mptcp_sock *msk = mptcp_sk(sk);
14281419
LIST_HEAD(conn_list);
1429-
u64 data_fin_tx_seq;
14301420

14311421
lock_sock(sk);
14321422

@@ -1440,17 +1430,14 @@ static void mptcp_close(struct sock *sk, long timeout)
14401430
spin_unlock_bh(&msk->join_list_lock);
14411431
list_splice_init(&msk->conn_list, &conn_list);
14421432

1443-
data_fin_tx_seq = msk->write_seq;
1433+
msk->snd_data_fin_enable = 1;
14441434

14451435
__mptcp_clear_xmit(sk);
14461436

14471437
release_sock(sk);
14481438

14491439
list_for_each_entry_safe(subflow, tmp, &conn_list, node) {
14501440
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
1451-
1452-
subflow->data_fin_tx_seq = data_fin_tx_seq;
1453-
subflow->data_fin_tx_enable = 1;
14541441
__mptcp_close_ssk(sk, ssk, subflow, timeout);
14551442
}
14561443

@@ -2146,10 +2133,12 @@ static int mptcp_shutdown(struct socket *sock, int how)
21462133
}
21472134

21482135
__mptcp_flush_join_list(msk);
2136+
msk->snd_data_fin_enable = 1;
2137+
21492138
mptcp_for_each_subflow(msk, subflow) {
21502139
struct sock *tcp_sk = mptcp_subflow_tcp_sock(subflow);
21512140

2152-
mptcp_subflow_shutdown(tcp_sk, how, 1, msk->write_seq);
2141+
mptcp_subflow_shutdown(tcp_sk, how);
21532142
}
21542143

21552144
/* Wake up anyone sleeping in poll. */

net/mptcp/protocol.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ struct mptcp_sock {
199199
unsigned long flags;
200200
bool can_ack;
201201
bool fully_established;
202+
bool snd_data_fin_enable;
202203
spinlock_t join_list_lock;
203204
struct work_struct work;
204205
struct list_head conn_list;
@@ -291,10 +292,8 @@ struct mptcp_subflow_context {
291292
backup : 1,
292293
data_avail : 1,
293294
rx_eof : 1,
294-
data_fin_tx_enable : 1,
295295
use_64bit_ack : 1, /* Set when we received a 64-bit DSN */
296296
can_ack : 1; /* only after processing the remote a key */
297-
u64 data_fin_tx_seq;
298297
u32 remote_nonce;
299298
u64 thmac;
300299
u32 local_nonce;

0 commit comments

Comments
 (0)