| .. | .. |
|---|
| 40 | 40 | sock_put((struct sock *)subflow_req->msk); |
|---|
| 41 | 41 | |
|---|
| 42 | 42 | mptcp_token_destroy_request(req); |
|---|
| 43 | | - tcp_request_sock_ops.destructor(req); |
|---|
| 44 | 43 | } |
|---|
| 45 | 44 | |
|---|
| 46 | 45 | static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2, |
|---|
| .. | .. |
|---|
| 276 | 275 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
|---|
| 277 | 276 | struct sock *sk = subflow->conn; |
|---|
| 278 | 277 | |
|---|
| 279 | | - tcp_set_state(ssk, TCP_CLOSE); |
|---|
| 280 | 278 | tcp_send_active_reset(ssk, GFP_ATOMIC); |
|---|
| 281 | 279 | tcp_done(ssk); |
|---|
| 282 | 280 | if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags) && |
|---|
| .. | .. |
|---|
| 359 | 357 | mptcp_subflow_reset(sk); |
|---|
| 360 | 358 | } |
|---|
| 361 | 359 | |
|---|
| 362 | | -struct request_sock_ops mptcp_subflow_request_sock_ops; |
|---|
| 363 | | -EXPORT_SYMBOL_GPL(mptcp_subflow_request_sock_ops); |
|---|
| 364 | | -static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops; |
|---|
| 360 | +static struct request_sock_ops mptcp_subflow_v4_request_sock_ops __ro_after_init; |
|---|
| 361 | +static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init; |
|---|
| 365 | 362 | |
|---|
| 366 | 363 | static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
|---|
| 367 | 364 | { |
|---|
| .. | .. |
|---|
| 373 | 370 | if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) |
|---|
| 374 | 371 | goto drop; |
|---|
| 375 | 372 | |
|---|
| 376 | | - return tcp_conn_request(&mptcp_subflow_request_sock_ops, |
|---|
| 373 | + return tcp_conn_request(&mptcp_subflow_v4_request_sock_ops, |
|---|
| 377 | 374 | &subflow_request_sock_ipv4_ops, |
|---|
| 378 | 375 | sk, skb); |
|---|
| 379 | 376 | drop: |
|---|
| .. | .. |
|---|
| 381 | 378 | return 0; |
|---|
| 382 | 379 | } |
|---|
| 383 | 380 | |
|---|
| 381 | +static void subflow_v4_req_destructor(struct request_sock *req) |
|---|
| 382 | +{ |
|---|
| 383 | + subflow_req_destructor(req); |
|---|
| 384 | + tcp_request_sock_ops.destructor(req); |
|---|
| 385 | +} |
|---|
| 386 | + |
|---|
| 384 | 387 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
|---|
| 385 | | -static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops; |
|---|
| 386 | | -static struct inet_connection_sock_af_ops subflow_v6_specific; |
|---|
| 387 | | -static struct inet_connection_sock_af_ops subflow_v6m_specific; |
|---|
| 388 | +static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init; |
|---|
| 389 | +static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init; |
|---|
| 390 | +static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init; |
|---|
| 391 | +static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init; |
|---|
| 388 | 392 | |
|---|
| 389 | 393 | static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb) |
|---|
| 390 | 394 | { |
|---|
| .. | .. |
|---|
| 403 | 407 | return 0; |
|---|
| 404 | 408 | } |
|---|
| 405 | 409 | |
|---|
| 406 | | - return tcp_conn_request(&mptcp_subflow_request_sock_ops, |
|---|
| 410 | + return tcp_conn_request(&mptcp_subflow_v6_request_sock_ops, |
|---|
| 407 | 411 | &subflow_request_sock_ipv6_ops, sk, skb); |
|---|
| 408 | 412 | |
|---|
| 409 | 413 | drop: |
|---|
| 410 | 414 | tcp_listendrop(sk); |
|---|
| 411 | 415 | return 0; /* don't send reset */ |
|---|
| 412 | 416 | } |
|---|
| 417 | + |
|---|
| 418 | +static void subflow_v6_req_destructor(struct request_sock *req) |
|---|
| 419 | +{ |
|---|
| 420 | + subflow_req_destructor(req); |
|---|
| 421 | + tcp6_request_sock_ops.destructor(req); |
|---|
| 422 | +} |
|---|
| 413 | 423 | #endif |
|---|
| 424 | + |
|---|
| 425 | +struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops, |
|---|
| 426 | + struct sock *sk_listener, |
|---|
| 427 | + bool attach_listener) |
|---|
| 428 | +{ |
|---|
| 429 | + if (ops->family == AF_INET) |
|---|
| 430 | + ops = &mptcp_subflow_v4_request_sock_ops; |
|---|
| 431 | +#if IS_ENABLED(CONFIG_MPTCP_IPV6) |
|---|
| 432 | + else if (ops->family == AF_INET6) |
|---|
| 433 | + ops = &mptcp_subflow_v6_request_sock_ops; |
|---|
| 434 | +#endif |
|---|
| 435 | + |
|---|
| 436 | + return inet_reqsk_alloc(ops, sk_listener, attach_listener); |
|---|
| 437 | +} |
|---|
| 438 | +EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc); |
|---|
| 414 | 439 | |
|---|
| 415 | 440 | /* validate hmac received in third ACK */ |
|---|
| 416 | 441 | static bool subflow_hmac_valid(const struct request_sock *req, |
|---|
| .. | .. |
|---|
| 636 | 661 | return child; |
|---|
| 637 | 662 | } |
|---|
| 638 | 663 | |
|---|
| 639 | | -static struct inet_connection_sock_af_ops subflow_specific; |
|---|
| 664 | +static struct inet_connection_sock_af_ops subflow_specific __ro_after_init; |
|---|
| 640 | 665 | |
|---|
| 641 | 666 | enum mapping_status { |
|---|
| 642 | 667 | MAPPING_OK, |
|---|
| .. | .. |
|---|
| 1017 | 1042 | } |
|---|
| 1018 | 1043 | } |
|---|
| 1019 | 1044 | |
|---|
| 1020 | | -static struct inet_connection_sock_af_ops * |
|---|
| 1045 | +static const struct inet_connection_sock_af_ops * |
|---|
| 1021 | 1046 | subflow_default_af_ops(struct sock *sk) |
|---|
| 1022 | 1047 | { |
|---|
| 1023 | 1048 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
|---|
| .. | .. |
|---|
| 1032 | 1057 | { |
|---|
| 1033 | 1058 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |
|---|
| 1034 | 1059 | struct inet_connection_sock *icsk = inet_csk(sk); |
|---|
| 1035 | | - struct inet_connection_sock_af_ops *target; |
|---|
| 1060 | + const struct inet_connection_sock_af_ops *target; |
|---|
| 1036 | 1061 | |
|---|
| 1037 | 1062 | target = mapped ? &subflow_v6m_specific : subflow_default_af_ops(sk); |
|---|
| 1038 | 1063 | |
|---|
| .. | .. |
|---|
| 1377 | 1402 | static int subflow_ops_init(struct request_sock_ops *subflow_ops) |
|---|
| 1378 | 1403 | { |
|---|
| 1379 | 1404 | subflow_ops->obj_size = sizeof(struct mptcp_subflow_request_sock); |
|---|
| 1380 | | - subflow_ops->slab_name = "request_sock_subflow"; |
|---|
| 1381 | 1405 | |
|---|
| 1382 | 1406 | subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name, |
|---|
| 1383 | 1407 | subflow_ops->obj_size, 0, |
|---|
| .. | .. |
|---|
| 1387 | 1411 | if (!subflow_ops->slab) |
|---|
| 1388 | 1412 | return -ENOMEM; |
|---|
| 1389 | 1413 | |
|---|
| 1390 | | - subflow_ops->destructor = subflow_req_destructor; |
|---|
| 1391 | | - |
|---|
| 1392 | 1414 | return 0; |
|---|
| 1393 | 1415 | } |
|---|
| 1394 | 1416 | |
|---|
| 1395 | 1417 | void __init mptcp_subflow_init(void) |
|---|
| 1396 | 1418 | { |
|---|
| 1397 | | - mptcp_subflow_request_sock_ops = tcp_request_sock_ops; |
|---|
| 1398 | | - if (subflow_ops_init(&mptcp_subflow_request_sock_ops) != 0) |
|---|
| 1399 | | - panic("MPTCP: failed to init subflow request sock ops\n"); |
|---|
| 1419 | + mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops; |
|---|
| 1420 | + mptcp_subflow_v4_request_sock_ops.slab_name = "request_sock_subflow_v4"; |
|---|
| 1421 | + mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor; |
|---|
| 1422 | + |
|---|
| 1423 | + if (subflow_ops_init(&mptcp_subflow_v4_request_sock_ops) != 0) |
|---|
| 1424 | + panic("MPTCP: failed to init subflow v4 request sock ops\n"); |
|---|
| 1400 | 1425 | |
|---|
| 1401 | 1426 | subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; |
|---|
| 1402 | 1427 | subflow_request_sock_ipv4_ops.init_req = subflow_v4_init_req; |
|---|
| .. | .. |
|---|
| 1407 | 1432 | subflow_specific.sk_rx_dst_set = subflow_finish_connect; |
|---|
| 1408 | 1433 | |
|---|
| 1409 | 1434 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
|---|
| 1435 | + /* In struct mptcp_subflow_request_sock, we assume the TCP request sock |
|---|
| 1436 | + * structures for v4 and v6 have the same size. It should not changed in |
|---|
| 1437 | + * the future but better to make sure to be warned if it is no longer |
|---|
| 1438 | + * the case. |
|---|
| 1439 | + */ |
|---|
| 1440 | + BUILD_BUG_ON(sizeof(struct tcp_request_sock) != sizeof(struct tcp6_request_sock)); |
|---|
| 1441 | + |
|---|
| 1442 | + mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops; |
|---|
| 1443 | + mptcp_subflow_v6_request_sock_ops.slab_name = "request_sock_subflow_v6"; |
|---|
| 1444 | + mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor; |
|---|
| 1445 | + |
|---|
| 1446 | + if (subflow_ops_init(&mptcp_subflow_v6_request_sock_ops) != 0) |
|---|
| 1447 | + panic("MPTCP: failed to init subflow v6 request sock ops\n"); |
|---|
| 1448 | + |
|---|
| 1410 | 1449 | subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; |
|---|
| 1411 | 1450 | subflow_request_sock_ipv6_ops.init_req = subflow_v6_init_req; |
|---|
| 1412 | 1451 | |
|---|