Skip to content

Commit b3ea6b2

Browse files
Paolo Abenikuba-moo
authored andcommitted
mptcp: consolidate initial ack seq generation
Currently the initial ack sequence is generated on demand whenever it's requested and the remote key is handy. The relevant code is scattered in different places and can lead to multiple, unneeded, crypto operations. This change consolidates the ack sequence generation code in a single helper, storing the sequence number at the subflow level. The above additionally saves a few conditional in fast-path and will simplify the upcoming fast-open implementation. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent fe33d38 commit b3ea6b2

File tree

4 files changed

+45
-45
lines changed

4 files changed

+45
-45
lines changed

net/mptcp/options.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,9 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
953953
return subflow->mp_capable;
954954
}
955955

956-
if (((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) ||
957-
((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo)) {
956+
if (subflow->remote_key_valid &&
957+
(((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) ||
958+
((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo))) {
958959
/* subflows are fully established as soon as we get any
959960
* additional ack, including ADD_ADDR.
960961
*/

net/mptcp/protocol.c

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,7 +3045,6 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
30453045
struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
30463046
struct sock *nsk = sk_clone_lock(sk, GFP_ATOMIC);
30473047
struct mptcp_sock *msk;
3048-
u64 ack_seq;
30493048

30503049
if (!nsk)
30513050
return NULL;
@@ -3071,15 +3070,6 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
30713070
msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
30723071
msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
30733072

3074-
if (mp_opt->suboptions & OPTIONS_MPTCP_MPC) {
3075-
msk->can_ack = true;
3076-
msk->remote_key = mp_opt->sndr_key;
3077-
mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
3078-
ack_seq++;
3079-
WRITE_ONCE(msk->ack_seq, ack_seq);
3080-
atomic64_set(&msk->rcv_wnd_sent, ack_seq);
3081-
}
3082-
30833073
sock_reset_flag(nsk, SOCK_RCU_FREE);
30843074
/* will be fully established after successful MPC subflow creation */
30853075
inet_sk_state_store(nsk, TCP_SYN_RECV);
@@ -3352,30 +3342,23 @@ void mptcp_finish_connect(struct sock *ssk)
33523342
struct mptcp_subflow_context *subflow;
33533343
struct mptcp_sock *msk;
33543344
struct sock *sk;
3355-
u64 ack_seq;
33563345

33573346
subflow = mptcp_subflow_ctx(ssk);
33583347
sk = subflow->conn;
33593348
msk = mptcp_sk(sk);
33603349

33613350
pr_debug("msk=%p, token=%u", sk, subflow->token);
33623351

3363-
mptcp_crypto_key_sha(subflow->remote_key, NULL, &ack_seq);
3364-
ack_seq++;
3365-
subflow->map_seq = ack_seq;
3352+
subflow->map_seq = subflow->iasn;
33663353
subflow->map_subflow_seq = 1;
33673354

33683355
/* the socket is not connected yet, no msk/subflow ops can access/race
33693356
* accessing the field below
33703357
*/
3371-
WRITE_ONCE(msk->remote_key, subflow->remote_key);
33723358
WRITE_ONCE(msk->local_key, subflow->local_key);
33733359
WRITE_ONCE(msk->write_seq, subflow->idsn + 1);
33743360
WRITE_ONCE(msk->snd_nxt, msk->write_seq);
3375-
WRITE_ONCE(msk->ack_seq, ack_seq);
3376-
WRITE_ONCE(msk->can_ack, 1);
33773361
WRITE_ONCE(msk->snd_una, msk->write_seq);
3378-
atomic64_set(&msk->rcv_wnd_sent, ack_seq);
33793362

33803363
mptcp_pm_new_connection(msk, ssk, 0);
33813364

net/mptcp/protocol.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ struct mptcp_subflow_context {
467467
send_fastclose : 1,
468468
send_infinite_map : 1,
469469
rx_eof : 1,
470-
can_ack : 1, /* only after processing the remote a key */
470+
remote_key_valid : 1, /* received the peer key from */
471471
disposable : 1, /* ctx can be free at ulp release time */
472472
stale : 1, /* unable to snd/rcv data, do not use for xmit */
473473
local_id_valid : 1, /* local_id is correctly initialized */
@@ -477,7 +477,10 @@ struct mptcp_subflow_context {
477477
u64 thmac;
478478
u32 local_nonce;
479479
u32 remote_token;
480-
u8 hmac[MPTCPOPT_HMAC_LEN];
480+
union {
481+
u8 hmac[MPTCPOPT_HMAC_LEN]; /* MPJ subflow only */
482+
u64 iasn; /* initial ack sequence number, MPC subflows only */
483+
};
481484
u8 local_id;
482485
u8 remote_id;
483486
u8 reset_seen:1;
@@ -603,7 +606,7 @@ unsigned int mptcp_stale_loss_cnt(const struct net *net);
603606
int mptcp_get_pm_type(const struct net *net);
604607
void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk);
605608
void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
606-
struct mptcp_options_received *mp_opt);
609+
const struct mptcp_options_received *mp_opt);
607610
bool __mptcp_retransmit_pending_data(struct sock *sk);
608611
void mptcp_check_and_set_pending(struct sock *sk);
609612
void __mptcp_push_pending(struct sock *sk, unsigned int flags);

net/mptcp/subflow.c

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -392,18 +392,41 @@ static void mptcp_set_connected(struct sock *sk)
392392
mptcp_data_unlock(sk);
393393
}
394394

395+
static void subflow_set_remote_key(struct mptcp_sock *msk,
396+
struct mptcp_subflow_context *subflow,
397+
const struct mptcp_options_received *mp_opt)
398+
{
399+
/* active MPC subflow will reach here multiple times:
400+
* at subflow_finish_connect() time and at 4th ack time
401+
*/
402+
if (subflow->remote_key_valid)
403+
return;
404+
405+
subflow->remote_key_valid = 1;
406+
subflow->remote_key = mp_opt->sndr_key;
407+
mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
408+
subflow->iasn++;
409+
410+
WRITE_ONCE(msk->remote_key, subflow->remote_key);
411+
WRITE_ONCE(msk->ack_seq, subflow->iasn);
412+
WRITE_ONCE(msk->can_ack, true);
413+
atomic64_set(&msk->rcv_wnd_sent, subflow->iasn);
414+
}
415+
395416
static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
396417
{
397418
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
398419
struct mptcp_options_received mp_opt;
399420
struct sock *parent = subflow->conn;
421+
struct mptcp_sock *msk;
400422

401423
subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);
402424

403425
/* be sure no special action on any packet other than syn-ack */
404426
if (subflow->conn_finished)
405427
return;
406428

429+
msk = mptcp_sk(parent);
407430
mptcp_propagate_sndbuf(parent, sk);
408431
subflow->rel_write_seq = 1;
409432
subflow->conn_finished = 1;
@@ -416,19 +439,16 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
416439
MPTCP_INC_STATS(sock_net(sk),
417440
MPTCP_MIB_MPCAPABLEACTIVEFALLBACK);
418441
mptcp_do_fallback(sk);
419-
pr_fallback(mptcp_sk(subflow->conn));
442+
pr_fallback(msk);
420443
goto fallback;
421444
}
422445

423446
if (mp_opt.suboptions & OPTION_MPTCP_CSUMREQD)
424-
WRITE_ONCE(mptcp_sk(parent)->csum_enabled, true);
447+
WRITE_ONCE(msk->csum_enabled, true);
425448
if (mp_opt.deny_join_id0)
426-
WRITE_ONCE(mptcp_sk(parent)->pm.remote_deny_join_id0, true);
449+
WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
427450
subflow->mp_capable = 1;
428-
subflow->can_ack = 1;
429-
subflow->remote_key = mp_opt.sndr_key;
430-
pr_debug("subflow=%p, remote_key=%llu", subflow,
431-
subflow->remote_key);
451+
subflow_set_remote_key(msk, subflow, &mp_opt);
432452
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK);
433453
mptcp_finish_connect(sk);
434454
mptcp_set_connected(parent);
@@ -466,15 +486,15 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
466486
subflow->mp_join = 1;
467487
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX);
468488

469-
if (subflow_use_different_dport(mptcp_sk(parent), sk)) {
489+
if (subflow_use_different_dport(msk, sk)) {
470490
pr_debug("synack inet_dport=%d %d",
471491
ntohs(inet_sk(sk)->inet_dport),
472492
ntohs(inet_sk(parent)->inet_dport));
473493
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINPORTSYNACKRX);
474494
}
475495
} else if (mptcp_check_fallback(sk)) {
476496
fallback:
477-
mptcp_rcv_space_init(mptcp_sk(parent), sk);
497+
mptcp_rcv_space_init(msk, sk);
478498
mptcp_set_connected(parent);
479499
}
480500
return;
@@ -637,13 +657,12 @@ static void subflow_drop_ctx(struct sock *ssk)
637657
}
638658

639659
void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
640-
struct mptcp_options_received *mp_opt)
660+
const struct mptcp_options_received *mp_opt)
641661
{
642662
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
643663

644-
subflow->remote_key = mp_opt->sndr_key;
664+
subflow_set_remote_key(msk, subflow, mp_opt);
645665
subflow->fully_established = 1;
646-
subflow->can_ack = 1;
647666
WRITE_ONCE(msk->fully_established, true);
648667
}
649668

@@ -1198,16 +1217,8 @@ static bool subflow_check_data_avail(struct sock *ssk)
11981217
if (WARN_ON_ONCE(!skb))
11991218
goto no_data;
12001219

1201-
/* if msk lacks the remote key, this subflow must provide an
1202-
* MP_CAPABLE-based mapping
1203-
*/
1204-
if (unlikely(!READ_ONCE(msk->can_ack))) {
1205-
if (!subflow->mpc_map)
1206-
goto fallback;
1207-
WRITE_ONCE(msk->remote_key, subflow->remote_key);
1208-
WRITE_ONCE(msk->ack_seq, subflow->map_seq);
1209-
WRITE_ONCE(msk->can_ack, true);
1210-
}
1220+
if (unlikely(!READ_ONCE(msk->can_ack)))
1221+
goto fallback;
12111222

12121223
old_ack = READ_ONCE(msk->ack_seq);
12131224
ack_seq = mptcp_subflow_get_mapped_dsn(subflow);
@@ -1480,6 +1491,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
14801491

14811492
mptcp_pm_get_flags_and_ifindex_by_id(msk, local_id,
14821493
&flags, &ifindex);
1494+
subflow->remote_key_valid = 1;
14831495
subflow->remote_key = msk->remote_key;
14841496
subflow->local_key = msk->local_key;
14851497
subflow->token = msk->token;
@@ -1873,6 +1885,7 @@ static void subflow_ulp_clone(const struct request_sock *req,
18731885
new_ctx->ssn_offset = subflow_req->ssn_offset;
18741886
new_ctx->mp_join = 1;
18751887
new_ctx->fully_established = 1;
1888+
new_ctx->remote_key_valid = 1;
18761889
new_ctx->backup = subflow_req->backup;
18771890
new_ctx->remote_id = subflow_req->remote_id;
18781891
new_ctx->token = subflow_req->token;

0 commit comments

Comments
 (0)