Mat Martineau says: ==================== mptcp: Fixes for 5.19 Several categories of fixes from the mptcp tree: Patches 1-3 are fixes related to MP_FAIL and FASTCLOSE, to make sure MIBs are accurate, and to handle MP_FAIL transmission and responses at the correct times. sk_timer conflicts are also resolved. Patches 4 and 6 handle two separate race conditions, one at socket shutdown and one with unaccepted subflows. Patch 5 makes sure read operations are not blocked during fallback to TCP. Patch 7 improves the diag selftest, which were incorrectly failing on slow machines (like the VMs used for CI testing). Patch 8 avoids possible symbol redefinition errors in the userspace mptcp.h file. Patch 9 fixes a selftest build issue with gcc 12. ====================
Unified · Split
| @@ -2,16 +2,17 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _UAPI_MPTCP_H |
| 3 | 3 | #define _UAPI_MPTCP_H |
| 4 | 4 | |
| 5 | +#ifndef __KERNEL__ | |
| 6 | +#include <netinet/in.h> /* for sockaddr_in and sockaddr_in6 */ | |
| 7 | +#include <sys/socket.h> /* for struct sockaddr */ | |
| 8 | +#endif | |
| 9 | + | |
| 5 | 10 | #include <linux/const.h> |
| 6 | 11 | #include <linux/types.h> |
| 7 | 12 | #include <linux/in.h> /* for sockaddr_in */ |
| 8 | 13 | #include <linux/in6.h> /* for sockaddr_in6 */ |
| 9 | 14 | #include <linux/socket.h> /* for sockaddr_storage and sa_family */ |
| 10 | 15 | |
| 11 | −#ifndef __KERNEL__ | |
| 12 | −#include <sys/socket.h> /* for struct sockaddr */ | |
| 13 | −#endif | |
| 14 | − | |
| 15 | 16 | #define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0) |
| 16 | 17 | #define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1) |
| 17 | 18 | #define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2) |
| @@ -765,6 +765,7 @@ static noinline bool mptcp_established_options_rst(struct sock *sk, struct sk_bu · 764 unmodified lines | ||
| 765 | 765 | opts->suboptions |= OPTION_MPTCP_RST; |
| 766 | 766 | opts->reset_transient = subflow->reset_transient; |
| 767 | 767 | opts->reset_reason = subflow->reset_reason; |
| 768 | + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPRSTTX); | |
| 768 | 769 | |
| 769 | 770 | return true; |
| 770 | 771 | } |
| @@ -788,6 +789,7 @@ static bool mptcp_established_options_fastclose(struct sock *sk, · 17 unmodified lines | ||
| 788 | 789 | opts->rcvr_key = msk->remote_key; |
| 789 | 790 | |
| 790 | 791 | pr_debug("FASTCLOSE key=%llu", opts->rcvr_key); |
| 792 | + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFASTCLOSETX); | |
| 791 | 793 | return true; |
| 792 | 794 | } |
| 793 | 795 | |
| @@ -809,6 +811,7 @@ static bool mptcp_established_options_mp_fail(struct sock *sk, · 15 unmodified lines | ||
| 809 | 811 | opts->fail_seq = subflow->map_seq; |
| 810 | 812 | |
| 811 | 813 | pr_debug("MP_FAIL fail_seq=%llu", opts->fail_seq); |
| 814 | + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX); | |
| 812 | 815 | |
| 813 | 816 | return true; |
| 814 | 817 | } |
| @@ -833,13 +836,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, · 18 unmodified lines | ||
| 833 | 836 | mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) { |
| 834 | 837 | *size += opt_size; |
| 835 | 838 | remaining -= opt_size; |
| 836 | − MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFASTCLOSETX); | |
| 837 | 839 | } |
| 838 | 840 | /* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */ |
| 839 | 841 | if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) { |
| 840 | 842 | *size += opt_size; |
| 841 | 843 | remaining -= opt_size; |
| 842 | − MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPRSTTX); | |
| 843 | 844 | } |
| 844 | 845 | return true; |
| 845 | 846 | } |
| @@ -966,7 +967,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, · 120 unmodified lines | ||
| 966 | 967 | goto reset; |
| 967 | 968 | subflow->mp_capable = 0; |
| 968 | 969 | pr_fallback(msk); |
| 969 | − __mptcp_do_fallback(msk); | |
| 970 | + mptcp_do_fallback(ssk); | |
| 970 | 971 | return false; |
| 971 | 972 | } |
| 972 | 973 | |
| @@ -299,23 +299,21 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) · 298 unmodified lines | ||
| 299 | 299 | { |
| 300 | 300 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |
| 301 | 301 | struct mptcp_sock *msk = mptcp_sk(subflow->conn); |
| 302 | − struct sock *s = (struct sock *)msk; | |
| 303 | 302 | |
| 304 | 303 | pr_debug("fail_seq=%llu", fail_seq); |
| 305 | 304 | |
| 306 | 305 | if (!READ_ONCE(msk->allow_infinite_fallback)) |
| 307 | 306 | return; |
| 308 | 307 | |
| 309 | − if (!READ_ONCE(subflow->mp_fail_response_expect)) { | |
| 308 | + if (!subflow->fail_tout) { | |
| 310 | 309 | pr_debug("send MP_FAIL response and infinite map"); |
| 311 | 310 | |
| 312 | 311 | subflow->send_mp_fail = 1; |
| 313 | − MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX); | |
| 314 | 312 | subflow->send_infinite_map = 1; |
| 315 | − } else if (!sock_flag(sk, SOCK_DEAD)) { | |
| 313 | + tcp_send_ack(sk); | |
| 314 | + } else { | |
| 316 | 315 | pr_debug("MP_FAIL response received"); |
| 317 | − | |
| 318 | − sk_stop_timer(s, &s->sk_timer); | |
| 316 | + WRITE_ONCE(subflow->fail_tout, 0); | |
| 319 | 317 | } |
| 320 | 318 | } |
| 321 | 319 | |
| @@ -500,7 +500,7 @@ static void mptcp_set_timeout(struct sock *sk) · 499 unmodified lines | ||
| 500 | 500 | __mptcp_set_timeout(sk, tout); |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | −static bool tcp_can_send_ack(const struct sock *ssk) | |
| 503 | +static inline bool tcp_can_send_ack(const struct sock *ssk) | |
| 504 | 504 | { |
| 505 | 505 | return !((1 << inet_sk_state_load(ssk)) & |
| 506 | 506 | (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN)); |
| @@ -1245,7 +1245,7 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, · 738 unmodified lines | ||
| 1245 | 1245 | MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX); |
| 1246 | 1246 | mptcp_subflow_ctx(ssk)->send_infinite_map = 0; |
| 1247 | 1247 | pr_fallback(msk); |
| 1248 | − __mptcp_do_fallback(msk); | |
| 1248 | + mptcp_do_fallback(ssk); | |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | 1251 | static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, |
| @@ -2175,21 +2175,6 @@ static void mptcp_retransmit_timer(struct timer_list *t) · 923 unmodified lines | ||
| 2175 | 2175 | sock_put(sk); |
| 2176 | 2176 | } |
| 2177 | 2177 | |
| 2178 | −static struct mptcp_subflow_context * | |
| 2179 | −mp_fail_response_expect_subflow(struct mptcp_sock *msk) | |
| 2180 | −{ | |
| 2181 | − struct mptcp_subflow_context *subflow, *ret = NULL; | |
| 2182 | − | |
| 2183 | − mptcp_for_each_subflow(msk, subflow) { | |
| 2184 | − if (READ_ONCE(subflow->mp_fail_response_expect)) { | |
| 2185 | − ret = subflow; | |
| 2186 | − break; | |
| 2187 | − } | |
| 2188 | − } | |
| 2189 | − | |
| 2190 | − return ret; | |
| 2191 | −} | |
| 2192 | − | |
| 2193 | 2178 | static void mptcp_timeout_timer(struct timer_list *t) |
| 2194 | 2179 | { |
| 2195 | 2180 | struct sock *sk = from_timer(sk, t, sk_timer); |
| @@ -2346,6 +2331,11 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, · 150 unmodified lines | ||
| 2346 | 2331 | kfree_rcu(subflow, rcu); |
| 2347 | 2332 | } else { |
| 2348 | 2333 | /* otherwise tcp will dispose of the ssk and subflow ctx */ |
| 2334 | + if (ssk->sk_state == TCP_LISTEN) { | |
| 2335 | + tcp_set_state(ssk, TCP_CLOSE); | |
| 2336 | + mptcp_subflow_queue_clean(ssk); | |
| 2337 | + inet_csk_listen_stop(ssk); | |
| 2338 | + } | |
| 2349 | 2339 | __tcp_close(ssk, 0); |
| 2350 | 2340 | |
| 2351 | 2341 | /* close acquired an extra ref */ |
| @@ -2518,27 +2508,50 @@ reset_timer: · 166 unmodified lines | ||
| 2518 | 2508 | mptcp_reset_timer(sk); |
| 2519 | 2509 | } |
| 2520 | 2510 | |
| 2511 | +/* schedule the timeout timer for the relevant event: either close timeout | |
| 2512 | + * or mp_fail timeout. The close timeout takes precedence on the mp_fail one | |
| 2513 | + */ | |
| 2514 | +void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout) | |
| 2515 | +{ | |
| 2516 | + struct sock *sk = (struct sock *)msk; | |
| 2517 | + unsigned long timeout, close_timeout; | |
| 2518 | + | |
| 2519 | + if (!fail_tout && !sock_flag(sk, SOCK_DEAD)) | |
| 2520 | + return; | |
| 2521 | + | |
| 2522 | + close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN; | |
| 2523 | + | |
| 2524 | + /* the close timeout takes precedence on the fail one, and here at least one of | |
| 2525 | + * them is active | |
| 2526 | + */ | |
| 2527 | + timeout = sock_flag(sk, SOCK_DEAD) ? close_timeout : fail_tout; | |
| 2528 | + | |
| 2529 | + sk_reset_timer(sk, &sk->sk_timer, timeout); | |
| 2530 | +} | |
| 2531 | + | |
| 2521 | 2532 | static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) |
| 2522 | 2533 | { |
| 2523 | − struct mptcp_subflow_context *subflow; | |
| 2524 | − struct sock *ssk; | |
| 2534 | + struct sock *ssk = msk->first; | |
| 2525 | 2535 | bool slow; |
| 2526 | 2536 | |
| 2527 | − subflow = mp_fail_response_expect_subflow(msk); | |
| 2528 | − if (subflow) { | |
| 2529 | − pr_debug("MP_FAIL doesn't respond, reset the subflow"); | |
| 2537 | + if (!ssk) | |
| 2538 | + return; | |
| 2530 | 2539 | |
| 2531 | − ssk = mptcp_subflow_tcp_sock(subflow); | |
| 2532 | − slow = lock_sock_fast(ssk); | |
| 2533 | − mptcp_subflow_reset(ssk); | |
| 2534 | − unlock_sock_fast(ssk, slow); | |
| 2535 | − } | |
| 2540 | + pr_debug("MP_FAIL doesn't respond, reset the subflow"); | |
| 2541 | + | |
| 2542 | + slow = lock_sock_fast(ssk); | |
| 2543 | + mptcp_subflow_reset(ssk); | |
| 2544 | + WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0); | |
| 2545 | + unlock_sock_fast(ssk, slow); | |
| 2546 | + | |
| 2547 | + mptcp_reset_timeout(msk, 0); | |
| 2536 | 2548 | } |
| 2537 | 2549 | |
| 2538 | 2550 | static void mptcp_worker(struct work_struct *work) |
| 2539 | 2551 | { |
| 2540 | 2552 | struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work); |
| 2541 | 2553 | struct sock *sk = &msk->sk.icsk_inet.sk; |
| 2554 | + unsigned long fail_tout; | |
| 2542 | 2555 | int state; |
| 2543 | 2556 | |
| 2544 | 2557 | lock_sock(sk); |
| @@ -2575,7 +2588,9 @@ static void mptcp_worker(struct work_struct *work) · 30 unmodified lines | ||
| 2575 | 2588 | if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) |
| 2576 | 2589 | __mptcp_retrans(sk); |
| 2577 | 2590 | |
| 2578 | − mptcp_mp_fail_no_response(msk); | |
| 2591 | + fail_tout = msk->first ? READ_ONCE(mptcp_subflow_ctx(msk->first)->fail_tout) : 0; | |
| 2592 | + if (fail_tout && time_after(jiffies, fail_tout)) | |
| 2593 | + mptcp_mp_fail_no_response(msk); | |
| 2579 | 2594 | |
| 2580 | 2595 | unlock: |
| 2581 | 2596 | release_sock(sk); |
| @@ -2822,6 +2837,7 @@ static void __mptcp_destroy_sock(struct sock *sk) · 240 unmodified lines | ||
| 2822 | 2837 | static void mptcp_close(struct sock *sk, long timeout) |
| 2823 | 2838 | { |
| 2824 | 2839 | struct mptcp_subflow_context *subflow; |
| 2840 | + struct mptcp_sock *msk = mptcp_sk(sk); | |
| 2825 | 2841 | bool do_cancel_work = false; |
| 2826 | 2842 | |
| 2827 | 2843 | lock_sock(sk); |
| @@ -2840,10 +2856,16 @@ static void mptcp_close(struct sock *sk, long timeout) · 12 unmodified lines | ||
| 2840 | 2856 | cleanup: |
| 2841 | 2857 | /* orphan all the subflows */ |
| 2842 | 2858 | inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32; |
| 2843 | − mptcp_for_each_subflow(mptcp_sk(sk), subflow) { | |
| 2859 | + mptcp_for_each_subflow(msk, subflow) { | |
| 2844 | 2860 | struct sock *ssk = mptcp_subflow_tcp_sock(subflow); |
| 2845 | 2861 | bool slow = lock_sock_fast_nested(ssk); |
| 2846 | 2862 | |
| 2863 | + /* since the close timeout takes precedence on the fail one, | |
| 2864 | + * cancel the latter | |
| 2865 | + */ | |
| 2866 | + if (ssk == msk->first) | |
| 2867 | + subflow->fail_tout = 0; | |
| 2868 | + | |
| 2847 | 2869 | sock_orphan(ssk); |
| 2848 | 2870 | unlock_sock_fast(ssk, slow); |
| 2849 | 2871 | } |
| @@ -2852,13 +2874,13 @@ cleanup: · 2 unmodified lines | ||
| 2852 | 2874 | sock_hold(sk); |
| 2853 | 2875 | pr_debug("msk=%p state=%d", sk, sk->sk_state); |
| 2854 | 2876 | if (mptcp_sk(sk)->token) |
| 2855 | − mptcp_event(MPTCP_EVENT_CLOSED, mptcp_sk(sk), NULL, GFP_KERNEL); | |
| 2877 | + mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL); | |
| 2856 | 2878 | |
| 2857 | 2879 | if (sk->sk_state == TCP_CLOSE) { |
| 2858 | 2880 | __mptcp_destroy_sock(sk); |
| 2859 | 2881 | do_cancel_work = true; |
| 2860 | 2882 | } else { |
| 2861 | − sk_reset_timer(sk, &sk->sk_timer, jiffies + TCP_TIMEWAIT_LEN); | |
| 2883 | + mptcp_reset_timeout(msk, 0); | |
| 2862 | 2884 | } |
| 2863 | 2885 | release_sock(sk); |
| 2864 | 2886 | if (do_cancel_work) |
| @@ -306,6 +306,7 @@ struct mptcp_sock { · 305 unmodified lines | ||
| 306 | 306 | |
| 307 | 307 | u32 setsockopt_seq; |
| 308 | 308 | char ca_name[TCP_CA_NAME_MAX]; |
| 309 | + struct mptcp_sock *dl_next; | |
| 309 | 310 | }; |
| 310 | 311 | |
| 311 | 312 | #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock) |
| @@ -468,7 +469,6 @@ struct mptcp_subflow_context { · 156 unmodified lines | ||
| 468 | 469 | local_id_valid : 1, /* local_id is correctly initialized */ |
| 469 | 470 | valid_csum_seen : 1; /* at least one csum validated */ |
| 470 | 471 | enum mptcp_data_avail data_avail; |
| 471 | − bool mp_fail_response_expect; | |
| 472 | 472 | u32 remote_nonce; |
| 473 | 473 | u64 thmac; |
| 474 | 474 | u32 local_nonce; |
| @@ -482,6 +482,7 @@ struct mptcp_subflow_context { · 7 unmodified lines | ||
| 482 | 482 | u8 stale_count; |
| 483 | 483 | |
| 484 | 484 | long delegated_status; |
| 485 | + unsigned long fail_tout; | |
| 485 | 486 | |
| 486 | 487 | ); |
| 487 | 488 | |
| @@ -608,6 +609,7 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk, · 120 unmodified lines | ||
| 608 | 609 | struct mptcp_subflow_context *subflow); |
| 609 | 610 | void mptcp_subflow_send_ack(struct sock *ssk); |
| 610 | 611 | void mptcp_subflow_reset(struct sock *ssk); |
| 612 | +void mptcp_subflow_queue_clean(struct sock *ssk); | |
| 611 | 613 | void mptcp_sock_graft(struct sock *sk, struct socket *parent); |
| 612 | 614 | struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk); |
| 613 | 615 | |
| @@ -662,6 +664,7 @@ void mptcp_get_options(const struct sk_buff *skb, · 48 unmodified lines | ||
| 662 | 664 | |
| 663 | 665 | void mptcp_finish_connect(struct sock *sk); |
| 664 | 666 | void __mptcp_set_connected(struct sock *sk); |
| 667 | +void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout); | |
| 665 | 668 | static inline bool mptcp_is_fully_established(struct sock *sk) |
| 666 | 669 | { |
| 667 | 670 | return inet_sk_state_load(sk) == TCP_ESTABLISHED && |
| @@ -926,12 +929,25 @@ static inline void __mptcp_do_fallback(struct mptcp_sock *msk) · 258 unmodified lines | ||
| 926 | 929 | set_bit(MPTCP_FALLBACK_DONE, &msk->flags); |
| 927 | 930 | } |
| 928 | 931 | |
| 929 | −static inline void mptcp_do_fallback(struct sock *sk) | |
| 932 | +static inline void mptcp_do_fallback(struct sock *ssk) | |
| 930 | 933 | { |
| 931 | − struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); | |
| 932 | − struct mptcp_sock *msk = mptcp_sk(subflow->conn); | |
| 934 | + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); | |
| 935 | + struct sock *sk = subflow->conn; | |
| 936 | + struct mptcp_sock *msk; | |
| 933 | 937 | |
| 938 | + msk = mptcp_sk(sk); | |
| 934 | 939 | __mptcp_do_fallback(msk); |
| 940 | + if (READ_ONCE(msk->snd_data_fin_enable) && !(ssk->sk_shutdown & SEND_SHUTDOWN)) { | |
| 941 | + gfp_t saved_allocation = ssk->sk_allocation; | |
| 942 | + | |
| 943 | + /* we are in a atomic (BH) scope, override ssk default for data | |
| 944 | + * fin allocation | |
| 945 | + */ | |
| 946 | + ssk->sk_allocation = GFP_ATOMIC; | |
| 947 | + ssk->sk_shutdown |= SEND_SHUTDOWN; | |
| 948 | + tcp_shutdown(ssk, SEND_SHUTDOWN); | |
| 949 | + ssk->sk_allocation = saved_allocation; | |
| 950 | + } | |
| 935 | 951 | } |
| 936 | 952 | |
| 937 | 953 | #define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a) |
| @@ -843,7 +843,8 @@ enum mapping_status { · 842 unmodified lines | ||
| 843 | 843 | MAPPING_INVALID, |
| 844 | 844 | MAPPING_EMPTY, |
| 845 | 845 | MAPPING_DATA_FIN, |
| 846 | − MAPPING_DUMMY | |
| 846 | + MAPPING_DUMMY, | |
| 847 | + MAPPING_BAD_CSUM | |
| 847 | 848 | }; |
| 848 | 849 | |
| 849 | 850 | static void dbg_bad_map(struct mptcp_subflow_context *subflow, u32 ssn) |
| @@ -958,11 +959,7 @@ static enum mapping_status validate_data_csum(struct sock *ssk, struct sk_buff * · 108 unmodified lines | ||
| 958 | 959 | subflow->map_data_csum); |
| 959 | 960 | if (unlikely(csum)) { |
| 960 | 961 | MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DATACSUMERR); |
| 961 | − if (subflow->mp_join || subflow->valid_csum_seen) { | |
| 962 | − subflow->send_mp_fail = 1; | |
| 963 | − MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPFAILTX); | |
| 964 | − } | |
| 965 | − return subflow->mp_join ? MAPPING_INVALID : MAPPING_DUMMY; | |
| 962 | + return MAPPING_BAD_CSUM; | |
| 966 | 963 | } |
| 967 | 964 | |
| 968 | 965 | subflow->valid_csum_seen = 1; |
| @@ -974,7 +971,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk, · 5 unmodified lines | ||
| 974 | 971 | { |
| 975 | 972 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
| 976 | 973 | bool csum_reqd = READ_ONCE(msk->csum_enabled); |
| 977 | − struct sock *sk = (struct sock *)msk; | |
| 978 | 974 | struct mptcp_ext *mpext; |
| 979 | 975 | struct sk_buff *skb; |
| 980 | 976 | u16 data_len; |
| @@ -1016,9 +1012,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk, · 35 unmodified lines | ||
| 1016 | 1012 | pr_debug("infinite mapping received"); |
| 1017 | 1013 | MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX); |
| 1018 | 1014 | subflow->map_data_len = 0; |
| 1019 | − if (!sock_flag(ssk, SOCK_DEAD)) | |
| 1020 | − sk_stop_timer(sk, &sk->sk_timer); | |
| 1021 | − | |
| 1022 | 1015 | return MAPPING_INVALID; |
| 1023 | 1016 | } |
| 1024 | 1017 | |
| @@ -1165,6 +1158,33 @@ static bool subflow_can_fallback(struct mptcp_subflow_context *subflow) · 140 unmodified lines | ||
| 1165 | 1158 | return !subflow->fully_established; |
| 1166 | 1159 | } |
| 1167 | 1160 | |
| 1161 | +static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) | |
| 1162 | +{ | |
| 1163 | + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); | |
| 1164 | + unsigned long fail_tout; | |
| 1165 | + | |
| 1166 | + /* greceful failure can happen only on the MPC subflow */ | |
| 1167 | + if (WARN_ON_ONCE(ssk != READ_ONCE(msk->first))) | |
| 1168 | + return; | |
| 1169 | + | |
| 1170 | + /* since the close timeout take precedence on the fail one, | |
| 1171 | + * no need to start the latter when the first is already set | |
| 1172 | + */ | |
| 1173 | + if (sock_flag((struct sock *)msk, SOCK_DEAD)) | |
| 1174 | + return; | |
| 1175 | + | |
| 1176 | + /* we don't need extreme accuracy here, use a zero fail_tout as special | |
| 1177 | + * value meaning no fail timeout at all; | |
| 1178 | + */ | |
| 1179 | + fail_tout = jiffies + TCP_RTO_MAX; | |
| 1180 | + if (!fail_tout) | |
| 1181 | + fail_tout = 1; | |
| 1182 | + WRITE_ONCE(subflow->fail_tout, fail_tout); | |
| 1183 | + tcp_send_ack(ssk); | |
| 1184 | + | |
| 1185 | + mptcp_reset_timeout(msk, subflow->fail_tout); | |
| 1186 | +} | |
| 1187 | + | |
| 1168 | 1188 | static bool subflow_check_data_avail(struct sock *ssk) |
| 1169 | 1189 | { |
| 1170 | 1190 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
| @@ -1184,10 +1204,8 @@ static bool subflow_check_data_avail(struct sock *ssk) · 13 unmodified lines | ||
| 1184 | 1204 | |
| 1185 | 1205 | status = get_mapping_status(ssk, msk); |
| 1186 | 1206 | trace_subflow_check_data_avail(status, skb_peek(&ssk->sk_receive_queue)); |
| 1187 | − if (unlikely(status == MAPPING_INVALID)) | |
| 1188 | − goto fallback; | |
| 1189 | − | |
| 1190 | − if (unlikely(status == MAPPING_DUMMY)) | |
| 1207 | + if (unlikely(status == MAPPING_INVALID || status == MAPPING_DUMMY || | |
| 1208 | + status == MAPPING_BAD_CSUM)) | |
| 1191 | 1209 | goto fallback; |
| 1192 | 1210 | |
| 1193 | 1211 | if (status != MAPPING_OK) |
| @@ -1229,22 +1247,17 @@ no_data: · 35 unmodified lines | ||
| 1229 | 1247 | fallback: |
| 1230 | 1248 | if (!__mptcp_check_fallback(msk)) { |
| 1231 | 1249 | /* RFC 8684 section 3.7. */ |
| 1232 | − if (subflow->send_mp_fail) { | |
| 1250 | + if (status == MAPPING_BAD_CSUM && | |
| 1251 | + (subflow->mp_join || subflow->valid_csum_seen)) { | |
| 1252 | + subflow->send_mp_fail = 1; | |
| 1253 | + | |
| 1233 | 1254 | if (!READ_ONCE(msk->allow_infinite_fallback)) { |
| 1234 | − ssk->sk_err = EBADMSG; | |
| 1235 | − tcp_set_state(ssk, TCP_CLOSE); | |
| 1236 | 1255 | subflow->reset_transient = 0; |
| 1237 | 1256 | subflow->reset_reason = MPTCP_RST_EMIDDLEBOX; |
| 1238 | − tcp_send_active_reset(ssk, GFP_ATOMIC); | |
| 1239 | − while ((skb = skb_peek(&ssk->sk_receive_queue))) | |
| 1240 | − sk_eat_skb(ssk, skb); | |
| 1241 | − } else if (!sock_flag(ssk, SOCK_DEAD)) { | |
| 1242 | − WRITE_ONCE(subflow->mp_fail_response_expect, true); | |
| 1243 | − sk_reset_timer((struct sock *)msk, | |
| 1244 | − &((struct sock *)msk)->sk_timer, | |
| 1245 | − jiffies + TCP_RTO_MAX); | |
| 1257 | + goto reset; | |
| 1246 | 1258 | } |
| 1247 | − WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); | |
| 1259 | + mptcp_subflow_fail(msk, ssk); | |
| 1260 | + WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_DATA_AVAIL); | |
| 1248 | 1261 | return true; |
| 1249 | 1262 | } |
| 1250 | 1263 | |
| @@ -1252,16 +1265,20 @@ fallback: · 1 unmodified line | ||
| 1252 | 1265 | /* fatal protocol error, close the socket. |
| 1253 | 1266 | * subflow_error_report() will introduce the appropriate barriers |
| 1254 | 1267 | */ |
| 1255 | − ssk->sk_err = EBADMSG; | |
| 1256 | − tcp_set_state(ssk, TCP_CLOSE); | |
| 1257 | 1268 | subflow->reset_transient = 0; |
| 1258 | 1269 | subflow->reset_reason = MPTCP_RST_EMPTCP; |
| 1270 | + | |
| 1271 | +reset: | |
| 1272 | + ssk->sk_err = EBADMSG; | |
| 1273 | + tcp_set_state(ssk, TCP_CLOSE); | |
| 1274 | + while ((skb = skb_peek(&ssk->sk_receive_queue))) | |
| 1275 | + sk_eat_skb(ssk, skb); | |
| 1259 | 1276 | tcp_send_active_reset(ssk, GFP_ATOMIC); |
| 1260 | 1277 | WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); |
| 1261 | 1278 | return false; |
| 1262 | 1279 | } |
| 1263 | 1280 | |
| 1264 | − __mptcp_do_fallback(msk); | |
| 1281 | + mptcp_do_fallback(ssk); | |
| 1265 | 1282 | } |
| 1266 | 1283 | |
| 1267 | 1284 | skb = skb_peek(&ssk->sk_receive_queue); |
| @@ -1706,6 +1723,58 @@ static void subflow_state_change(struct sock *sk) · 438 unmodified lines | ||
| 1706 | 1723 | } |
| 1707 | 1724 | } |
| 1708 | 1725 | |
| 1726 | +void mptcp_subflow_queue_clean(struct sock *listener_ssk) | |
| 1727 | +{ | |
| 1728 | + struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue; | |
| 1729 | + struct mptcp_sock *msk, *next, *head = NULL; | |
| 1730 | + struct request_sock *req; | |
| 1731 | + | |
| 1732 | + /* build a list of all unaccepted mptcp sockets */ | |
| 1733 | + spin_lock_bh(&queue->rskq_lock); | |
| 1734 | + for (req = queue->rskq_accept_head; req; req = req->dl_next) { | |
| 1735 | + struct mptcp_subflow_context *subflow; | |
| 1736 | + struct sock *ssk = req->sk; | |
| 1737 | + struct mptcp_sock *msk; | |
| 1738 | + | |
| 1739 | + if (!sk_is_mptcp(ssk)) | |
| 1740 | + continue; | |
| 1741 | + | |
| 1742 | + subflow = mptcp_subflow_ctx(ssk); | |
| 1743 | + if (!subflow || !subflow->conn) | |
| 1744 | + continue; | |
| 1745 | + | |
| 1746 | + /* skip if already in list */ | |
| 1747 | + msk = mptcp_sk(subflow->conn); | |
| 1748 | + if (msk->dl_next || msk == head) | |
| 1749 | + continue; | |
| 1750 | + | |
| 1751 | + msk->dl_next = head; | |
| 1752 | + head = msk; | |
| 1753 | + } | |
| 1754 | + spin_unlock_bh(&queue->rskq_lock); | |
| 1755 | + if (!head) | |
| 1756 | + return; | |
| 1757 | + | |
| 1758 | + /* can't acquire the msk socket lock under the subflow one, | |
| 1759 | + * or will cause ABBA deadlock | |
| 1760 | + */ | |
| 1761 | + release_sock(listener_ssk); | |
| 1762 | + | |
| 1763 | + for (msk = head; msk; msk = next) { | |
| 1764 | + struct sock *sk = (struct sock *)msk; | |
| 1765 | + bool slow; | |
| 1766 | + | |
| 1767 | + slow = lock_sock_fast_nested(sk); | |
| 1768 | + next = msk->dl_next; | |
| 1769 | + msk->first = NULL; | |
| 1770 | + msk->dl_next = NULL; | |
| 1771 | + unlock_sock_fast(sk, slow); | |
| 1772 | + } | |
| 1773 | + | |
| 1774 | + /* we are still under the listener msk socket lock */ | |
| 1775 | + lock_sock_nested(listener_ssk, SINGLE_DEPTH_NESTING); | |
| 1776 | +} | |
| 1777 | + | |
| 1709 | 1778 | static int subflow_ulp_init(struct sock *sk) |
| 1710 | 1779 | { |
| 1711 | 1780 | struct inet_connection_sock *icsk = inet_csk(sk); |
| @@ -61,6 +61,39 @@ chk_msk_nr() · 60 unmodified lines | ||
| 61 | 61 | __chk_nr "grep -c token:" $* |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | +wait_msk_nr() | |
| 65 | +{ | |
| 66 | + local condition="grep -c token:" | |
| 67 | + local expected=$1 | |
| 68 | + local timeout=20 | |
| 69 | + local msg nr | |
| 70 | + local max=0 | |
| 71 | + local i=0 | |
| 72 | + | |
| 73 | + shift 1 | |
| 74 | + msg=$* | |
| 75 | + | |
| 76 | + while [ $i -lt $timeout ]; do | |
| 77 | + nr=$(ss -inmHMN $ns | $condition) | |
| 78 | + [ $nr == $expected ] && break; | |
| 79 | + [ $nr -gt $max ] && max=$nr | |
| 80 | + i=$((i + 1)) | |
| 81 | + sleep 1 | |
| 82 | + done | |
| 83 | + | |
| 84 | + printf "%-50s" "$msg" | |
| 85 | + if [ $i -ge $timeout ]; then | |
| 86 | + echo "[ fail ] timeout while expecting $expected max $max last $nr" | |
| 87 | + ret=$test_cnt | |
| 88 | + elif [ $nr != $expected ]; then | |
| 89 | + echo "[ fail ] expected $expected found $nr" | |
| 90 | + ret=$test_cnt | |
| 91 | + else | |
| 92 | + echo "[ ok ]" | |
| 93 | + fi | |
| 94 | + test_cnt=$((test_cnt+1)) | |
| 95 | +} | |
| 96 | + | |
| 64 | 97 | chk_msk_fallback_nr() |
| 65 | 98 | { |
| 66 | 99 | __chk_nr "grep -c fallback" $* |
| @@ -146,7 +179,7 @@ ip -n $ns link set dev lo up · 79 unmodified lines | ||
| 146 | 179 | echo "a" | \ |
| 147 | 180 | timeout ${timeout_test} \ |
| 148 | 181 | ip netns exec $ns \ |
| 149 | − ./mptcp_connect -p 10000 -l -t ${timeout_poll} \ | |
| 182 | + ./mptcp_connect -p 10000 -l -t ${timeout_poll} -w 20 \ | |
| 150 | 183 | 0.0.0.0 >/dev/null & |
| 151 | 184 | wait_local_port_listen $ns 10000 |
| 152 | 185 | chk_msk_nr 0 "no msk on netns creation" |
| @@ -155,7 +188,7 @@ chk_msk_listen 10000 · 2 unmodified lines | ||
| 155 | 188 | echo "b" | \ |
| 156 | 189 | timeout ${timeout_test} \ |
| 157 | 190 | ip netns exec $ns \ |
| 158 | − ./mptcp_connect -p 10000 -r 0 -t ${timeout_poll} \ | |
| 191 | + ./mptcp_connect -p 10000 -r 0 -t ${timeout_poll} -w 20 \ | |
| 159 | 192 | 127.0.0.1 >/dev/null & |
| 160 | 193 | wait_connected $ns 10000 |
| 161 | 194 | chk_msk_nr 2 "after MPC handshake " |
| @@ -167,13 +200,13 @@ flush_pids · 5 unmodified lines | ||
| 167 | 200 | echo "a" | \ |
| 168 | 201 | timeout ${timeout_test} \ |
| 169 | 202 | ip netns exec $ns \ |
| 170 | − ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} \ | |
| 203 | + ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} -w 20 \ | |
| 171 | 204 | 0.0.0.0 >/dev/null & |
| 172 | 205 | wait_local_port_listen $ns 10001 |
| 173 | 206 | echo "b" | \ |
| 174 | 207 | timeout ${timeout_test} \ |
| 175 | 208 | ip netns exec $ns \ |
| 176 | − ./mptcp_connect -p 10001 -r 0 -t ${timeout_poll} \ | |
| 209 | + ./mptcp_connect -p 10001 -r 0 -t ${timeout_poll} -w 20 \ | |
| 177 | 210 | 127.0.0.1 >/dev/null & |
| 178 | 211 | wait_connected $ns 10001 |
| 179 | 212 | chk_msk_fallback_nr 1 "check fallback" |
| @@ -184,7 +217,7 @@ for I in `seq 1 $NR_CLIENTS`; do · 4 unmodified lines | ||
| 184 | 217 | echo "a" | \ |
| 185 | 218 | timeout ${timeout_test} \ |
| 186 | 219 | ip netns exec $ns \ |
| 187 | − ./mptcp_connect -p $((I+10001)) -l -w 10 \ | |
| 220 | + ./mptcp_connect -p $((I+10001)) -l -w 20 \ | |
| 188 | 221 | -t ${timeout_poll} 0.0.0.0 >/dev/null & |
| 189 | 222 | done |
| 190 | 223 | wait_local_port_listen $ns $((NR_CLIENTS + 10001)) |
| @@ -193,12 +226,11 @@ for I in `seq 1 $NR_CLIENTS`; do · 2 unmodified lines | ||
| 193 | 226 | echo "b" | \ |
| 194 | 227 | timeout ${timeout_test} \ |
| 195 | 228 | ip netns exec $ns \ |
| 196 | − ./mptcp_connect -p $((I+10001)) -w 10 \ | |
| 229 | + ./mptcp_connect -p $((I+10001)) -w 20 \ | |
| 197 | 230 | -t ${timeout_poll} 127.0.0.1 >/dev/null & |
| 198 | 231 | done |
| 199 | −sleep 1.5 | |
| 200 | 232 | |
| 201 | −chk_msk_nr $((NR_CLIENTS*2)) "many msk socket present" | |
| 233 | +wait_msk_nr $((NR_CLIENTS*2)) "many msk socket present" | |
| 202 | 234 | flush_pids |
| 203 | 235 | |
| 204 | 236 | exit $ret |
| @@ -265,7 +265,7 @@ static void sock_test_tcpulp(int sock, int proto, unsigned int line) · 264 unmodified lines | ||
| 265 | 265 | static int sock_listen_mptcp(const char * const listenaddr, |
| 266 | 266 | const char * const port) |
| 267 | 267 | { |
| 268 | − int sock; | |
| 268 | + int sock = -1; | |
| 269 | 269 | struct addrinfo hints = { |
| 270 | 270 | .ai_protocol = IPPROTO_TCP, |
| 271 | 271 | .ai_socktype = SOCK_STREAM, |
| @@ -88,7 +88,7 @@ static void xgetaddrinfo(const char *node, const char *service, · 87 unmodified lines | ||
| 88 | 88 | static int sock_listen_mptcp(const char * const listenaddr, |
| 89 | 89 | const char * const port) |
| 90 | 90 | { |
| 91 | − int sock; | |
| 91 | + int sock = -1; | |
| 92 | 92 | struct addrinfo hints = { |
| 93 | 93 | .ai_protocol = IPPROTO_TCP, |
| 94 | 94 | .ai_socktype = SOCK_STREAM, |
| @@ -136,7 +136,7 @@ static void xgetaddrinfo(const char *node, const char *service, · 135 unmodified lines | ||
| 136 | 136 | static int sock_listen_mptcp(const char * const listenaddr, |
| 137 | 137 | const char * const port) |
| 138 | 138 | { |
| 139 | − int sock; | |
| 139 | + int sock = -1; | |
| 140 | 140 | struct addrinfo hints = { |
| 141 | 141 | .ai_protocol = IPPROTO_TCP, |
| 142 | 142 | .ai_socktype = SOCK_STREAM, |