Skip to content

Commit f3c7a6e

Browse files
committed
Merge branch 'mptcp-cope-with-syncookie-on-MP_JOINs'
Paolo Abeni says: ==================== mptcp: cope with syncookie on MP_JOINs Currently syncookies on MP_JOIN connections are not handled correctly: the connections fallback to TCP and are kept alive instead of resetting them at fallback time. The first patch propagates the required information up to syn_recv_sock time, and the 2nd patch addresses the unifying the error path for all MP_JOIN requests. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5eea3a6 + 9e365ff commit f3c7a6e

File tree

2 files changed

+28
-30
lines changed

2 files changed

+28
-30
lines changed

net/mptcp/protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ struct mptcp_subflow_request_sock {
249249
u64 thmac;
250250
u32 local_nonce;
251251
u32 remote_nonce;
252+
struct mptcp_sock *msk;
252253
};
253254

254255
static inline struct mptcp_subflow_request_sock *

net/mptcp/subflow.c

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ static void subflow_req_destructor(struct request_sock *req)
6969

7070
pr_debug("subflow_req=%p", subflow_req);
7171

72+
if (subflow_req->msk)
73+
sock_put((struct sock *)subflow_req->msk);
74+
7275
if (subflow_req->mp_capable)
7376
mptcp_token_destroy_request(subflow_req->token);
7477
tcp_request_sock_ops.destructor(req);
@@ -86,8 +89,8 @@ static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
8689
}
8790

8891
/* validate received token and create truncated hmac and nonce for SYN-ACK */
89-
static bool subflow_token_join_request(struct request_sock *req,
90-
const struct sk_buff *skb)
92+
static struct mptcp_sock *subflow_token_join_request(struct request_sock *req,
93+
const struct sk_buff *skb)
9194
{
9295
struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
9396
u8 hmac[SHA256_DIGEST_SIZE];
@@ -97,13 +100,13 @@ static bool subflow_token_join_request(struct request_sock *req,
97100
msk = mptcp_token_get_sock(subflow_req->token);
98101
if (!msk) {
99102
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINNOTOKEN);
100-
return false;
103+
return NULL;
101104
}
102105

103106
local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)req);
104107
if (local_id < 0) {
105108
sock_put((struct sock *)msk);
106-
return false;
109+
return NULL;
107110
}
108111
subflow_req->local_id = local_id;
109112

@@ -114,9 +117,7 @@ static bool subflow_token_join_request(struct request_sock *req,
114117
subflow_req->remote_nonce, hmac);
115118

116119
subflow_req->thmac = get_unaligned_be64(hmac);
117-
118-
sock_put((struct sock *)msk);
119-
return true;
120+
return msk;
120121
}
121122

122123
static void subflow_init_req(struct request_sock *req,
@@ -133,6 +134,7 @@ static void subflow_init_req(struct request_sock *req,
133134

134135
subflow_req->mp_capable = 0;
135136
subflow_req->mp_join = 0;
137+
subflow_req->msk = NULL;
136138

137139
#ifdef CONFIG_TCP_MD5SIG
138140
/* no MPTCP if MD5SIG is enabled on this socket or we may run out of
@@ -166,12 +168,9 @@ static void subflow_init_req(struct request_sock *req,
166168
subflow_req->remote_id = mp_opt.join_id;
167169
subflow_req->token = mp_opt.token;
168170
subflow_req->remote_nonce = mp_opt.nonce;
169-
pr_debug("token=%u, remote_nonce=%u", subflow_req->token,
170-
subflow_req->remote_nonce);
171-
if (!subflow_token_join_request(req, skb)) {
172-
subflow_req->mp_join = 0;
173-
// @@ need to trigger RST
174-
}
171+
subflow_req->msk = subflow_token_join_request(req, skb);
172+
pr_debug("token=%u, remote_nonce=%u msk=%p", subflow_req->token,
173+
subflow_req->remote_nonce, subflow_req->msk);
175174
}
176175
}
177176

@@ -354,23 +353,17 @@ static bool subflow_hmac_valid(const struct request_sock *req,
354353
const struct mptcp_subflow_request_sock *subflow_req;
355354
u8 hmac[SHA256_DIGEST_SIZE];
356355
struct mptcp_sock *msk;
357-
bool ret;
358356

359357
subflow_req = mptcp_subflow_rsk(req);
360-
msk = mptcp_token_get_sock(subflow_req->token);
358+
msk = subflow_req->msk;
361359
if (!msk)
362360
return false;
363361

364362
subflow_generate_hmac(msk->remote_key, msk->local_key,
365363
subflow_req->remote_nonce,
366364
subflow_req->local_nonce, hmac);
367365

368-
ret = true;
369-
if (crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN))
370-
ret = false;
371-
372-
sock_put((struct sock *)msk);
373-
return ret;
366+
return !crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN);
374367
}
375368

376369
static void mptcp_sock_destruct(struct sock *sk)
@@ -438,22 +431,25 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
438431
struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
439432
struct mptcp_subflow_request_sock *subflow_req;
440433
struct mptcp_options_received mp_opt;
441-
bool fallback_is_fatal = false;
434+
bool fallback, fallback_is_fatal;
442435
struct sock *new_msk = NULL;
443-
bool fallback = false;
444436
struct sock *child;
445437

446438
pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
447439

448-
/* we need later a valid 'mp_capable' value even when options are not
449-
* parsed
440+
/* After child creation we must look for 'mp_capable' even when options
441+
* are not parsed
450442
*/
451443
mp_opt.mp_capable = 0;
452-
if (tcp_rsk(req)->is_mptcp == 0)
444+
445+
/* hopefully temporary handling for MP_JOIN+syncookie */
446+
subflow_req = mptcp_subflow_rsk(req);
447+
fallback_is_fatal = subflow_req->mp_join;
448+
fallback = !tcp_rsk(req)->is_mptcp;
449+
if (fallback)
453450
goto create_child;
454451

455452
/* if the sk is MP_CAPABLE, we try to fetch the client key */
456-
subflow_req = mptcp_subflow_rsk(req);
457453
if (subflow_req->mp_capable) {
458454
if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) {
459455
/* here we can receive and accept an in-window,
@@ -474,12 +470,11 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
474470
if (!new_msk)
475471
fallback = true;
476472
} else if (subflow_req->mp_join) {
477-
fallback_is_fatal = true;
478473
mptcp_get_options(skb, &mp_opt);
479474
if (!mp_opt.mp_join ||
480475
!subflow_hmac_valid(req, &mp_opt)) {
481476
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
482-
return NULL;
477+
fallback = true;
483478
}
484479
}
485480

@@ -522,10 +517,12 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
522517
} else if (ctx->mp_join) {
523518
struct mptcp_sock *owner;
524519

525-
owner = mptcp_token_get_sock(ctx->token);
520+
owner = subflow_req->msk;
526521
if (!owner)
527522
goto dispose_child;
528523

524+
/* move the msk reference ownership to the subflow */
525+
subflow_req->msk = NULL;
529526
ctx->conn = (struct sock *)owner;
530527
if (!mptcp_finish_join(child))
531528
goto dispose_child;

0 commit comments

Comments
 (0)