@@ -133,7 +133,6 @@ static void subflow_init_req(struct request_sock *req,
133
133
134
134
subflow_req -> mp_capable = 0 ;
135
135
subflow_req -> mp_join = 0 ;
136
- subflow_req -> remote_key_valid = 0 ;
137
136
138
137
#ifdef CONFIG_TCP_MD5SIG
139
138
/* no MPTCP if MD5SIG is enabled on this socket or we may run out of
@@ -376,6 +375,17 @@ static void mptcp_force_close(struct sock *sk)
376
375
sk_common_release (sk );
377
376
}
378
377
378
+ static void subflow_ulp_fallback (struct sock * sk ,
379
+ struct mptcp_subflow_context * old_ctx )
380
+ {
381
+ struct inet_connection_sock * icsk = inet_csk (sk );
382
+
383
+ mptcp_subflow_tcp_fallback (sk , old_ctx );
384
+ icsk -> icsk_ulp_ops = NULL ;
385
+ rcu_assign_pointer (icsk -> icsk_ulp_data , NULL );
386
+ tcp_sk (sk )-> is_mptcp = 0 ;
387
+ }
388
+
379
389
static struct sock * subflow_syn_recv_sock (const struct sock * sk ,
380
390
struct sk_buff * skb ,
381
391
struct request_sock * req ,
@@ -388,10 +398,12 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
388
398
struct tcp_options_received opt_rx ;
389
399
bool fallback_is_fatal = false;
390
400
struct sock * new_msk = NULL ;
401
+ bool fallback = false;
391
402
struct sock * child ;
392
403
393
404
pr_debug ("listener=%p, req=%p, conn=%p" , listener , req , listener -> conn );
394
405
406
+ opt_rx .mptcp .mp_capable = 0 ;
395
407
if (tcp_rsk (req )-> is_mptcp == 0 )
396
408
goto create_child ;
397
409
@@ -406,20 +418,16 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
406
418
goto create_msk ;
407
419
}
408
420
409
- opt_rx .mptcp .mp_capable = 0 ;
410
421
mptcp_get_options (skb , & opt_rx );
411
- if (opt_rx .mptcp .mp_capable ) {
412
- subflow_req -> remote_key = opt_rx .mptcp .sndr_key ;
413
- subflow_req -> remote_key_valid = 1 ;
414
- } else {
415
- subflow_req -> mp_capable = 0 ;
422
+ if (!opt_rx .mptcp .mp_capable ) {
423
+ fallback = true;
416
424
goto create_child ;
417
425
}
418
426
419
427
create_msk :
420
- new_msk = mptcp_sk_clone (listener -> conn , req );
428
+ new_msk = mptcp_sk_clone (listener -> conn , & opt_rx , req );
421
429
if (!new_msk )
422
- subflow_req -> mp_capable = 0 ;
430
+ fallback = true ;
423
431
} else if (subflow_req -> mp_join ) {
424
432
fallback_is_fatal = true;
425
433
opt_rx .mptcp .mp_join = 0 ;
@@ -438,12 +446,18 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
438
446
if (child && * own_req ) {
439
447
struct mptcp_subflow_context * ctx = mptcp_subflow_ctx (child );
440
448
441
- /* we have null ctx on TCP fallback, which is fatal on
442
- * MPJ handshake
449
+ /* we need to fallback on ctx allocation failure and on pre-reqs
450
+ * checking above. In the latter scenario we additionally need
451
+ * to reset the context to non MPTCP status.
443
452
*/
444
- if (!ctx ) {
453
+ if (!ctx || fallback ) {
445
454
if (fallback_is_fatal )
446
455
goto close_child ;
456
+
457
+ if (ctx ) {
458
+ subflow_ulp_fallback (child , ctx );
459
+ kfree_rcu (ctx , rcu );
460
+ }
447
461
goto out ;
448
462
}
449
463
@@ -455,6 +469,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
455
469
mptcp_pm_new_connection (mptcp_sk (new_msk ), 1 );
456
470
ctx -> conn = new_msk ;
457
471
new_msk = NULL ;
472
+
473
+ /* with OoO packets we can reach here without ingress
474
+ * mpc option
475
+ */
476
+ ctx -> remote_key = opt_rx .mptcp .sndr_key ;
477
+ ctx -> fully_established = opt_rx .mptcp .mp_capable ;
478
+ ctx -> can_ack = opt_rx .mptcp .mp_capable ;
458
479
} else if (ctx -> mp_join ) {
459
480
struct mptcp_sock * owner ;
460
481
@@ -474,6 +495,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
474
495
/* dispose of the left over mptcp master, if any */
475
496
if (unlikely (new_msk ))
476
497
mptcp_force_close (new_msk );
498
+
499
+ /* check for expected invariant - should never trigger, just help
500
+ * catching eariler subtle bugs
501
+ */
502
+ WARN_ON_ONCE (* own_req && child && tcp_sk (child )-> is_mptcp &&
503
+ (!mptcp_subflow_ctx (child ) ||
504
+ !mptcp_subflow_ctx (child )-> conn ));
477
505
return child ;
478
506
479
507
close_child :
@@ -1076,17 +1104,6 @@ static void subflow_ulp_release(struct sock *sk)
1076
1104
kfree_rcu (ctx , rcu );
1077
1105
}
1078
1106
1079
- static void subflow_ulp_fallback (struct sock * sk ,
1080
- struct mptcp_subflow_context * old_ctx )
1081
- {
1082
- struct inet_connection_sock * icsk = inet_csk (sk );
1083
-
1084
- mptcp_subflow_tcp_fallback (sk , old_ctx );
1085
- icsk -> icsk_ulp_ops = NULL ;
1086
- rcu_assign_pointer (icsk -> icsk_ulp_data , NULL );
1087
- tcp_sk (sk )-> is_mptcp = 0 ;
1088
- }
1089
-
1090
1107
static void subflow_ulp_clone (const struct request_sock * req ,
1091
1108
struct sock * newsk ,
1092
1109
const gfp_t priority )
@@ -1120,9 +1137,6 @@ static void subflow_ulp_clone(const struct request_sock *req,
1120
1137
* is fully established only after we receive the remote key
1121
1138
*/
1122
1139
new_ctx -> mp_capable = 1 ;
1123
- new_ctx -> fully_established = subflow_req -> remote_key_valid ;
1124
- new_ctx -> can_ack = subflow_req -> remote_key_valid ;
1125
- new_ctx -> remote_key = subflow_req -> remote_key ;
1126
1140
new_ctx -> local_key = subflow_req -> local_key ;
1127
1141
new_ctx -> token = subflow_req -> token ;
1128
1142
new_ctx -> ssn_offset = subflow_req -> ssn_offset ;
0 commit comments