subflow.c (603ea288dc53dfabf823bf7d38e401a945309492) subflow.c (d39dceca388ad0e4f748836806349ebe09282283)
1// SPDX-License-Identifier: GPL-2.0
2/* Multipath TCP
3 *
4 * Copyright (c) 2017 - 2019, Intel Corporation.
5 */
6
7#define pr_fmt(fmt) "MPTCP: " fmt
8

--- 55 unchanged lines hidden (view full) ---

64}
65
66static void subflow_req_destructor(struct request_sock *req)
67{
68 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
69
70 pr_debug("subflow_req=%p", subflow_req);
71
1// SPDX-License-Identifier: GPL-2.0
2/* Multipath TCP
3 *
4 * Copyright (c) 2017 - 2019, Intel Corporation.
5 */
6
7#define pr_fmt(fmt) "MPTCP: " fmt
8

--- 55 unchanged lines hidden (view full) ---

64}
65
66static void subflow_req_destructor(struct request_sock *req)
67{
68 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
69
70 pr_debug("subflow_req=%p", subflow_req);
71
72 if (subflow_req->msk)
73 sock_put((struct sock *)subflow_req->msk);
74
72 if (subflow_req->mp_capable)
73 mptcp_token_destroy_request(subflow_req->token);
74 tcp_request_sock_ops.destructor(req);
75}
76
77static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
78 void *hmac)
79{
80 u8 msg[8];
81
82 put_unaligned_be32(nonce1, &msg[0]);
83 put_unaligned_be32(nonce2, &msg[4]);
84
85 mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
86}
87
88/* validate received token and create truncated hmac and nonce for SYN-ACK */
75 if (subflow_req->mp_capable)
76 mptcp_token_destroy_request(subflow_req->token);
77 tcp_request_sock_ops.destructor(req);
78}
79
80static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
81 void *hmac)
82{
83 u8 msg[8];
84
85 put_unaligned_be32(nonce1, &msg[0]);
86 put_unaligned_be32(nonce2, &msg[4]);
87
88 mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
89}
90
91/* validate received token and create truncated hmac and nonce for SYN-ACK */
89static bool subflow_token_join_request(struct request_sock *req,
90 const struct sk_buff *skb)
92static struct mptcp_sock *subflow_token_join_request(struct request_sock *req,
93 const struct sk_buff *skb)
91{
92 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
93 u8 hmac[SHA256_DIGEST_SIZE];
94 struct mptcp_sock *msk;
95 int local_id;
96
97 msk = mptcp_token_get_sock(subflow_req->token);
98 if (!msk) {
99 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINNOTOKEN);
94{
95 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
96 u8 hmac[SHA256_DIGEST_SIZE];
97 struct mptcp_sock *msk;
98 int local_id;
99
100 msk = mptcp_token_get_sock(subflow_req->token);
101 if (!msk) {
102 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINNOTOKEN);
100 return false;
103 return NULL;
101 }
102
103 local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)req);
104 if (local_id < 0) {
105 sock_put((struct sock *)msk);
104 }
105
106 local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)req);
107 if (local_id < 0) {
108 sock_put((struct sock *)msk);
106 return false;
109 return NULL;
107 }
108 subflow_req->local_id = local_id;
109
110 get_random_bytes(&subflow_req->local_nonce, sizeof(u32));
111
112 subflow_generate_hmac(msk->local_key, msk->remote_key,
113 subflow_req->local_nonce,
114 subflow_req->remote_nonce, hmac);
115
116 subflow_req->thmac = get_unaligned_be64(hmac);
110 }
111 subflow_req->local_id = local_id;
112
113 get_random_bytes(&subflow_req->local_nonce, sizeof(u32));
114
115 subflow_generate_hmac(msk->local_key, msk->remote_key,
116 subflow_req->local_nonce,
117 subflow_req->remote_nonce, hmac);
118
119 subflow_req->thmac = get_unaligned_be64(hmac);
117
118 sock_put((struct sock *)msk);
119 return true;
120 return msk;
120}
121
122static void subflow_init_req(struct request_sock *req,
123 const struct sock *sk_listener,
124 struct sk_buff *skb)
125{
126 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);
127 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
128 struct mptcp_options_received mp_opt;
129
130 pr_debug("subflow_req=%p, listener=%p", subflow_req, listener);
131
132 mptcp_get_options(skb, &mp_opt);
133
134 subflow_req->mp_capable = 0;
135 subflow_req->mp_join = 0;
121}
122
123static void subflow_init_req(struct request_sock *req,
124 const struct sock *sk_listener,
125 struct sk_buff *skb)
126{
127 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);
128 struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
129 struct mptcp_options_received mp_opt;
130
131 pr_debug("subflow_req=%p, listener=%p", subflow_req, listener);
132
133 mptcp_get_options(skb, &mp_opt);
134
135 subflow_req->mp_capable = 0;
136 subflow_req->mp_join = 0;
137 subflow_req->msk = NULL;
136
137#ifdef CONFIG_TCP_MD5SIG
138 /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
139 * TCP option space.
140 */
141 if (rcu_access_pointer(tcp_sk(sk_listener)->md5sig_info))
142 return;
143#endif

--- 17 unchanged lines hidden (view full) ---

161 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
162 } else if (mp_opt.mp_join && listener->request_mptcp) {
163 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
164 subflow_req->mp_join = 1;
165 subflow_req->backup = mp_opt.backup;
166 subflow_req->remote_id = mp_opt.join_id;
167 subflow_req->token = mp_opt.token;
168 subflow_req->remote_nonce = mp_opt.nonce;
138
139#ifdef CONFIG_TCP_MD5SIG
140 /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
141 * TCP option space.
142 */
143 if (rcu_access_pointer(tcp_sk(sk_listener)->md5sig_info))
144 return;
145#endif

--- 17 unchanged lines hidden (view full) ---

163 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
164 } else if (mp_opt.mp_join && listener->request_mptcp) {
165 subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;
166 subflow_req->mp_join = 1;
167 subflow_req->backup = mp_opt.backup;
168 subflow_req->remote_id = mp_opt.join_id;
169 subflow_req->token = mp_opt.token;
170 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);
175 }
176}
177
178static void subflow_v4_init_req(struct request_sock *req,
179 const struct sock *sk_listener,
180 struct sk_buff *skb)
181{
182 tcp_rsk(req)->is_mptcp = 1;

--- 166 unchanged lines hidden (view full) ---

349
350/* validate hmac received in third ACK */
351static bool subflow_hmac_valid(const struct request_sock *req,
352 const struct mptcp_options_received *mp_opt)
353{
354 const struct mptcp_subflow_request_sock *subflow_req;
355 u8 hmac[SHA256_DIGEST_SIZE];
356 struct mptcp_sock *msk;
174 }
175}
176
177static void subflow_v4_init_req(struct request_sock *req,
178 const struct sock *sk_listener,
179 struct sk_buff *skb)
180{
181 tcp_rsk(req)->is_mptcp = 1;

--- 166 unchanged lines hidden (view full) ---

348
349/* validate hmac received in third ACK */
350static bool subflow_hmac_valid(const struct request_sock *req,
351 const struct mptcp_options_received *mp_opt)
352{
353 const struct mptcp_subflow_request_sock *subflow_req;
354 u8 hmac[SHA256_DIGEST_SIZE];
355 struct mptcp_sock *msk;
357 bool ret;
358
359 subflow_req = mptcp_subflow_rsk(req);
356
357 subflow_req = mptcp_subflow_rsk(req);
360 msk = mptcp_token_get_sock(subflow_req->token);
358 msk = subflow_req->msk;
361 if (!msk)
362 return false;
363
364 subflow_generate_hmac(msk->remote_key, msk->local_key,
365 subflow_req->remote_nonce,
366 subflow_req->local_nonce, hmac);
367
359 if (!msk)
360 return false;
361
362 subflow_generate_hmac(msk->remote_key, msk->local_key,
363 subflow_req->remote_nonce,
364 subflow_req->local_nonce, hmac);
365
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);
374}
375
376static void mptcp_sock_destruct(struct sock *sk)
377{
378 /* if new mptcp socket isn't accepted, it is free'd
379 * from the tcp listener sockets request queue, linked
380 * from req->sk. The tcp socket is released.
381 * This calls the ULP release function which will

--- 51 unchanged lines hidden (view full) ---

433 struct request_sock *req,
434 struct dst_entry *dst,
435 struct request_sock *req_unhash,
436 bool *own_req)
437{
438 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
439 struct mptcp_subflow_request_sock *subflow_req;
440 struct mptcp_options_received mp_opt;
367}
368
369static void mptcp_sock_destruct(struct sock *sk)
370{
371 /* if new mptcp socket isn't accepted, it is free'd
372 * from the tcp listener sockets request queue, linked
373 * from req->sk. The tcp socket is released.
374 * This calls the ULP release function which will

--- 51 unchanged lines hidden (view full) ---

426 struct request_sock *req,
427 struct dst_entry *dst,
428 struct request_sock *req_unhash,
429 bool *own_req)
430{
431 struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
432 struct mptcp_subflow_request_sock *subflow_req;
433 struct mptcp_options_received mp_opt;
441 bool fallback_is_fatal = false;
434 bool fallback, fallback_is_fatal;
442 struct sock *new_msk = NULL;
435 struct sock *new_msk = NULL;
443 bool fallback = false;
444 struct sock *child;
445
446 pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
447
436 struct sock *child;
437
438 pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
439
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
450 */
451 mp_opt.mp_capable = 0;
442 */
443 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)
453 goto create_child;
454
455 /* if the sk is MP_CAPABLE, we try to fetch the client key */
450 goto create_child;
451
452 /* if the sk is MP_CAPABLE, we try to fetch the client key */
456 subflow_req = mptcp_subflow_rsk(req);
457 if (subflow_req->mp_capable) {
458 if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) {
459 /* here we can receive and accept an in-window,
460 * out-of-order pkt, which will not carry the MP_CAPABLE
461 * opt even on mptcp enabled paths
462 */
463 goto create_msk;
464 }

--- 4 unchanged lines hidden (view full) ---

469 goto create_child;
470 }
471
472create_msk:
473 new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req);
474 if (!new_msk)
475 fallback = true;
476 } else if (subflow_req->mp_join) {
453 if (subflow_req->mp_capable) {
454 if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) {
455 /* here we can receive and accept an in-window,
456 * out-of-order pkt, which will not carry the MP_CAPABLE
457 * opt even on mptcp enabled paths
458 */
459 goto create_msk;
460 }

--- 4 unchanged lines hidden (view full) ---

465 goto create_child;
466 }
467
468create_msk:
469 new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req);
470 if (!new_msk)
471 fallback = true;
472 } else if (subflow_req->mp_join) {
477 fallback_is_fatal = true;
478 mptcp_get_options(skb, &mp_opt);
479 if (!mp_opt.mp_join ||
480 !subflow_hmac_valid(req, &mp_opt)) {
481 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
473 mptcp_get_options(skb, &mp_opt);
474 if (!mp_opt.mp_join ||
475 !subflow_hmac_valid(req, &mp_opt)) {
476 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
482 return NULL;
477 fallback = true;
483 }
484 }
485
486create_child:
487 child = listener->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
488 req_unhash, own_req);
489
490 if (child && *own_req) {

--- 26 unchanged lines hidden (view full) ---

517 * mpc option
518 */
519 ctx->remote_key = mp_opt.sndr_key;
520 ctx->fully_established = mp_opt.mp_capable;
521 ctx->can_ack = mp_opt.mp_capable;
522 } else if (ctx->mp_join) {
523 struct mptcp_sock *owner;
524
478 }
479 }
480
481create_child:
482 child = listener->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
483 req_unhash, own_req);
484
485 if (child && *own_req) {

--- 26 unchanged lines hidden (view full) ---

512 * mpc option
513 */
514 ctx->remote_key = mp_opt.sndr_key;
515 ctx->fully_established = mp_opt.mp_capable;
516 ctx->can_ack = mp_opt.mp_capable;
517 } else if (ctx->mp_join) {
518 struct mptcp_sock *owner;
519
525 owner = mptcp_token_get_sock(ctx->token);
520 owner = subflow_req->msk;
526 if (!owner)
527 goto dispose_child;
528
521 if (!owner)
522 goto dispose_child;
523
524 /* move the msk reference ownership to the subflow */
525 subflow_req->msk = NULL;
529 ctx->conn = (struct sock *)owner;
530 if (!mptcp_finish_join(child))
531 goto dispose_child;
532
533 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKRX);
534 tcp_rsk(req)->drop_req = true;
535 }
536 }

--- 716 unchanged lines hidden (view full) ---

1253 if (!subflow_ops->slab)
1254 return -ENOMEM;
1255
1256 subflow_ops->destructor = subflow_req_destructor;
1257
1258 return 0;
1259}
1260
526 ctx->conn = (struct sock *)owner;
527 if (!mptcp_finish_join(child))
528 goto dispose_child;
529
530 SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKRX);
531 tcp_rsk(req)->drop_req = true;
532 }
533 }

--- 716 unchanged lines hidden (view full) ---

1250 if (!subflow_ops->slab)
1251 return -ENOMEM;
1252
1253 subflow_ops->destructor = subflow_req_destructor;
1254
1255 return 0;
1256}
1257
1261void mptcp_subflow_init(void)
1258void __init mptcp_subflow_init(void)
1262{
1263 subflow_request_sock_ops = tcp_request_sock_ops;
1264 if (subflow_ops_init(&subflow_request_sock_ops) != 0)
1265 panic("MPTCP: failed to init subflow request sock ops\n");
1266
1267 subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
1268 subflow_request_sock_ipv4_ops.init_req = subflow_v4_init_req;
1269

--- 29 unchanged lines hidden ---
1259{
1260 subflow_request_sock_ops = tcp_request_sock_ops;
1261 if (subflow_ops_init(&subflow_request_sock_ops) != 0)
1262 panic("MPTCP: failed to init subflow request sock ops\n");
1263
1264 subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
1265 subflow_request_sock_ipv4_ops.init_req = subflow_v4_init_req;
1266

--- 29 unchanged lines hidden ---