From 01f64f0543826d7e5addf649c56923398ea90a1e Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 29 Jun 2022 22:33:09 +0200 Subject: [PATCH] Update MPTCP --- .../generic/hack-5.4/690-mptcp_v0.96.patch | 255 ++++++++---------- 1 file changed, 105 insertions(+), 150 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_v0.96.patch b/root/target/linux/generic/hack-5.4/690-mptcp_v0.96.patch index 7c2d820a..25d2279e 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_v0.96.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_v0.96.patch @@ -287,10 +287,10 @@ index 34c4436fd18f..828f79528b32 100644 union { diff --git a/include/net/mptcp.h b/include/net/mptcp.h new file mode 100644 -index 000000000000..bb18dacc310f +index 000000000000..630977f67614 --- /dev/null +++ b/include/net/mptcp.h -@@ -0,0 +1,1549 @@ +@@ -0,0 +1,1548 @@ +/* + * MPTCP implementation + * @@ -1207,7 +1207,6 @@ index 000000000000..bb18dacc310f +int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); +void mptcp_enable_sock(struct sock *sk); +void mptcp_disable_sock(struct sock *sk); -+void mptcp_disable_static_key(void); +void mptcp_cookies_reqsk_init(struct request_sock *req, + struct mptcp_options_received *mopt, + struct sk_buff *skb); @@ -2118,7 +2117,7 @@ index 7f213cfcb3cc..c1be2daccb54 100644 /* Keeping track of sockets in use */ #ifdef CONFIG_PROC_FS diff --git a/include/net/tcp.h b/include/net/tcp.h -index 65be8bd1f0f4..b31fc84741a0 100644 +index 65be8bd1f0f4..cf89f928640e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -182,6 +182,7 @@ @@ -2425,10 +2424,10 @@ index 65be8bd1f0f4..b31fc84741a0 100644 } +#ifdef CONFIG_MPTCP -+extern struct static_key mptcp_static_key; ++DECLARE_STATIC_KEY_FALSE(mptcp_static_key); +static inline bool mptcp(const struct tcp_sock *tp) +{ -+ return static_key_false(&mptcp_static_key) && tp->mpc; ++ return static_branch_unlikely(&mptcp_static_key) && tp->mpc; +} +#else +static inline bool mptcp(const struct tcp_sock *tp) @@ -2917,7 +2916,7 @@ index a03036456221..aebb337662c3 100644 IFF_ALLMULTI)); diff --git a/net/core/filter.c b/net/core/filter.c -index e16b2b5cda98..d038517091c6 100644 +index b0df4ddbe30c..ea4deefb0a70 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -73,6 +73,7 @@ @@ -3187,7 +3186,7 @@ index a926de2e42b5..6d73dc6e2586 100644 default "dctcp" if DEFAULT_DCTCP default "cdg" if DEFAULT_CDG diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index a7a6b1adb698..8ebca975f8c8 100644 +index a7a6b1adb698..e1ccbe866a90 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -100,6 +100,7 @@ @@ -3198,17 +3197,7 @@ index a7a6b1adb698..8ebca975f8c8 100644 #include #include #include -@@ -150,6 +151,9 @@ void inet_sock_destruct(struct sock *sk) - return; - } - -+ if (sock_flag(sk, SOCK_MPTCP)) -+ mptcp_disable_static_key(); -+ - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(refcount_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); -@@ -227,6 +231,8 @@ int inet_listen(struct socket *sock, int backlog) +@@ -227,6 +228,8 @@ int inet_listen(struct socket *sock, int backlog) tcp_fastopen_init_key_once(sock_net(sk)); } @@ -3217,7 +3206,7 @@ index a7a6b1adb698..8ebca975f8c8 100644 err = inet_csk_listen_start(sk, backlog); if (err) goto out; -@@ -244,8 +250,7 @@ int inet_listen(struct socket *sock, int backlog) +@@ -244,8 +247,7 @@ int inet_listen(struct socket *sock, int backlog) * Create an inet socket. */ @@ -3227,7 +3216,7 @@ index a7a6b1adb698..8ebca975f8c8 100644 { struct sock *sk; struct inet_protosw *answer; -@@ -739,6 +744,24 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags, +@@ -739,6 +741,24 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags, lock_sock(sk2); sock_rps_record_flow(sk2); @@ -3252,7 +3241,7 @@ index a7a6b1adb698..8ebca975f8c8 100644 WARN_ON(!((1 << sk2->sk_state) & (TCPF_ESTABLISHED | TCPF_SYN_RECV | TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1981,6 +2004,9 @@ static int __init inet_init(void) +@@ -1981,6 +2001,9 @@ static int __init inet_init(void) if (init_ipv4_mibs()) panic("%s: Cannot init ipv4 mibs\n", __func__); @@ -7681,10 +7670,10 @@ index 063898cae3e5..78d91dfc3f06 100644 /* thinking of making this const? Don't. diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig new file mode 100644 -index 000000000000..6e05dab4c632 +index 000000000000..1a7e9bbc766d --- /dev/null +++ b/net/mptcp/Kconfig -@@ -0,0 +1,154 @@ +@@ -0,0 +1,155 @@ +# +# MPTCP configuration +# @@ -7767,6 +7756,7 @@ index 000000000000..6e05dab4c632 + default "fullmesh" if DEFAULT_FULLMESH + default "ndiffports" if DEFAULT_NDIFFPORTS + default "binder" if DEFAULT_BINDER ++ default "netlink" if DEFAULT_NETLINK + default "default" + +menuconfig MPTCP_SCHED_ADVANCED @@ -9396,10 +9386,10 @@ index 000000000000..9eb7628053f6 +MODULE_VERSION("0.1"); diff --git a/net/mptcp/mptcp_ctrl.c b/net/mptcp/mptcp_ctrl.c new file mode 100644 -index 000000000000..38c97eaa0ddc +index 000000000000..9a1b5a048b70 --- /dev/null +++ b/net/mptcp/mptcp_ctrl.c -@@ -0,0 +1,3346 @@ +@@ -0,0 +1,3302 @@ +/* + * MPTCP implementation - MPTCP-control + * @@ -9479,7 +9469,7 @@ index 000000000000..38c97eaa0ddc + +bool mptcp_init_failed __read_mostly; + -+struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; ++DEFINE_STATIC_KEY_FALSE(mptcp_static_key); +EXPORT_SYMBOL(mptcp_static_key); + +static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn); @@ -9793,71 +9783,14 @@ index 000000000000..38c97eaa0ddc + mptcp_key_hash(tp->mptcp_ver, tp->mptcp_loc_key, &tp->mptcp_loc_token, NULL); +} + -+#ifdef CONFIG_JUMP_LABEL -+static atomic_t mptcp_needed_deferred; -+static atomic_t mptcp_wanted; -+ -+static void mptcp_clear(struct work_struct *work) -+{ -+ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); -+ int wanted; -+ -+ wanted = atomic_add_return(deferred, &mptcp_wanted); -+ if (wanted > 0) -+ static_key_enable(&mptcp_static_key); -+ else -+ static_key_disable(&mptcp_static_key); -+} -+ -+static DECLARE_WORK(mptcp_work, mptcp_clear); -+#endif -+ -+static void mptcp_enable_static_key_bh(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 0) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) -+ return; -+ } -+ atomic_inc(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ +static void mptcp_enable_static_key(void) +{ -+#ifdef CONFIG_JUMP_LABEL -+ atomic_inc(&mptcp_wanted); -+ static_key_enable(&mptcp_static_key); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} ++ if (!static_branch_unlikely(&mptcp_static_key)) { ++ static int __mptcp_static_key = 0; + -+void mptcp_disable_static_key(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 1) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) -+ return; ++ if (cmpxchg(&__mptcp_static_key, 0, 1) == 0) ++ static_branch_enable(&mptcp_static_key); + } -+ atomic_dec(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_dec(&mptcp_static_key); -+#endif +} + +void mptcp_enable_sock(struct sock *sk) @@ -9898,8 +9831,6 @@ index 000000000000..38c97eaa0ddc + else + inet_csk(sk)->icsk_af_ops = &ipv6_specific; +#endif -+ -+ mptcp_disable_static_key(); + } +} + @@ -10120,8 +10051,6 @@ index 000000000000..38c97eaa0ddc + mptcp_mpcb_cleanup(tp->mpcb); + } + -+ WARN_ON(!static_key_false(&mptcp_static_key)); -+ + /* Must be called here, because this will decrement the jump-label. */ + inet_sock_destruct(sk); +} @@ -10682,6 +10611,28 @@ index 000000000000..38c97eaa0ddc + meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; +} + ++/* Inspired by inet_csk_prepare_forced_close */ ++static void mptcp_icsk_forced_close(struct sock *sk) ++{ ++ /* The problem with inet_csk_prepare_forced_close is that it unlocks ++ * before calling tcp_done. That is fine for sockets that are not ++ * yet in the ehash table. But for us we already are there. Thus, ++ * if we unlock we run the risk of processing packets while inside ++ * tcp_done() and friends. That can cause all kind of problems... ++ */ ++ ++ /* The below has to be done to allow calling inet_csk_destroy_sock */ ++ sock_set_flag(sk, SOCK_DEAD); ++ percpu_counter_inc(sk->sk_prot->orphan_count); ++ inet_sk(sk)->inet_num = 0; ++ ++ tcp_done(sk); ++ ++ /* sk_clone_lock locked the socket and set refcnt to 2 */ ++ bh_unlock_sock(sk); ++ sock_put(sk); ++} ++ +static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, + int rem_key_set, __u8 mptcp_ver, u32 window) +{ @@ -10897,10 +10848,8 @@ index 000000000000..38c97eaa0ddc + meta_sk->sk_max_ack_backlog = 32; + meta_sk->sk_ack_backlog = 0; + -+ if (!sock_flag(meta_sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); ++ if (!sock_flag(meta_sk, SOCK_MPTCP)) + sock_set_flag(meta_sk, SOCK_MPTCP); -+ } + + /* Redefine function-pointers as the meta-sk is now fully ready */ + meta_tp->mpc = 1; @@ -10937,8 +10886,7 @@ index 000000000000..38c97eaa0ddc + kmem_cache_free(mptcp_sock_cache, master_tp->mptcp); + master_tp->mptcp = NULL; + -+ inet_csk_prepare_forced_close(master_sk); -+ tcp_done(master_sk); ++ mptcp_icsk_forced_close(master_sk); + return -EINVAL; + +err_inherit_port: @@ -10993,9 +10941,8 @@ index 000000000000..38c97eaa0ddc + tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); + /* No more space for more subflows? */ + if (!tp->mptcp->path_index) { -+ WARN_ON(is_master_tp(tp)); -+ + kmem_cache_free(mptcp_sock_cache, tp->mptcp); ++ tp->mptcp = NULL; + return -EPERM; + } + @@ -11005,10 +10952,8 @@ index 000000000000..38c97eaa0ddc + tp->mpcb = mpcb; + tp->meta_sk = meta_sk; + -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); ++ if (!sock_flag(sk, SOCK_MPTCP)) + sock_set_flag(sk, SOCK_MPTCP); -+ } + + tp->mpc = 1; + tp->ops = &mptcp_sub_specific; @@ -11696,8 +11641,7 @@ index 000000000000..38c97eaa0ddc + if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, + mtreq->rem_key_set, mtreq->mptcp_ver, + child_tp->snd_wnd)) { -+ inet_csk_prepare_forced_close(meta_sk); -+ tcp_done(meta_sk); ++ mptcp_icsk_forced_close(meta_sk); + + return -ENOBUFS; + } @@ -11918,9 +11862,11 @@ index 000000000000..38c97eaa0ddc + /* Drop this request - sock creation failed. */ + inet_csk_reqsk_queue_drop(meta_sk, req); + reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ inet_csk_prepare_forced_close(child); -+ tcp_done(child); ++ ++ mptcp_icsk_forced_close(child); ++ + bh_unlock_sock(meta_sk); ++ + return meta_sk; +} + @@ -17527,10 +17473,10 @@ index 000000000000..7ce97409e1e2 +} diff --git a/net/mptcp/mptcp_ipv4.c b/net/mptcp/mptcp_ipv4.c new file mode 100644 -index 000000000000..7594c8bafb81 +index 000000000000..c908e02c72e1 --- /dev/null +++ b/net/mptcp/mptcp_ipv4.c -@@ -0,0 +1,432 @@ +@@ -0,0 +1,433 @@ +/* + * MPTCP implementation - IPv4-specific functions + * @@ -17798,7 +17744,7 @@ index 000000000000..7594c8bafb81 +{ + struct tcp_sock *tp; + struct sock *sk; -+ struct sockaddr_in loc_in, rem_in; ++ struct sockaddr_in sockaddr; + struct socket_alloc sock_full; + struct socket *sock = (struct socket *)&sock_full; + int ret; @@ -17836,38 +17782,39 @@ index 000000000000..7594c8bafb81 + timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); + + /** Then, connect the socket to the peer */ -+ loc_in.sin_family = AF_INET; -+ rem_in.sin_family = AF_INET; -+ loc_in.sin_port = sport; -+ if (rem->port) -+ rem_in.sin_port = rem->port; -+ else -+ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin_addr = loc->addr; -+ rem_in.sin_addr = rem->addr; ++ sockaddr.sin_family = AF_INET; ++ sockaddr.sin_port = sport; ++ sockaddr.sin_addr = loc->addr; + + if (loc->if_idx) + sk->sk_bound_dev_if = loc->if_idx; + -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, ++ ret = kernel_bind(sock, (struct sockaddr *)&sockaddr, + sizeof(struct sockaddr_in)); + if (ret < 0) { + net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", + __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin_addr, loc->if_idx, ret); ++ &sockaddr.sin_addr, loc->if_idx, ret); + goto error; + } + -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin_addr, -+ ntohs(loc_in.sin_port), &rem_in.sin_addr, -+ ntohs(rem_in.sin_port), loc->if_idx); -+ + if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) + tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); + -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, ++ sockaddr.sin_family = AF_INET; ++ if (rem->port) ++ sockaddr.sin_port = rem->port; ++ else ++ sockaddr.sin_port = inet_sk(meta_sk)->inet_dport; ++ sockaddr.sin_addr = rem->addr; ++ ++ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, &loc->addr, ++ ntohs(sport), &sockaddr.sin_addr, ++ ntohs(sockaddr.sin_port), loc->if_idx); ++ ++ ret = kernel_connect(sock, (struct sockaddr *)&sockaddr, + sizeof(struct sockaddr_in), O_NONBLOCK); + if (ret < 0 && ret != -EINPROGRESS) { + net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", @@ -17965,10 +17912,10 @@ index 000000000000..7594c8bafb81 +} diff --git a/net/mptcp/mptcp_ipv6.c b/net/mptcp/mptcp_ipv6.c new file mode 100644 -index 000000000000..fa13a99b735e +index 000000000000..ebe3f5f97460 --- /dev/null +++ b/net/mptcp/mptcp_ipv6.c -@@ -0,0 +1,481 @@ +@@ -0,0 +1,482 @@ +/* + * MPTCP implementation - IPv6-specific functions + * @@ -18265,7 +18212,7 @@ index 000000000000..fa13a99b735e +{ + struct tcp_sock *tp; + struct sock *sk; -+ struct sockaddr_in6 loc_in, rem_in; ++ struct sockaddr_in6 sockaddr; + struct socket_alloc sock_full; + struct socket *sock = (struct socket *)&sock_full; + int ret; @@ -18303,38 +18250,39 @@ index 000000000000..fa13a99b735e + timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); + + /** Then, connect the socket to the peer */ -+ loc_in.sin6_family = AF_INET6; -+ rem_in.sin6_family = AF_INET6; -+ loc_in.sin6_port = sport; -+ if (rem->port) -+ rem_in.sin6_port = rem->port; -+ else -+ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin6_addr = loc->addr; -+ rem_in.sin6_addr = rem->addr; ++ sockaddr.sin6_family = AF_INET6; ++ sockaddr.sin6_port = sport; ++ sockaddr.sin6_addr = loc->addr; + + if (loc->if_idx) + sk->sk_bound_dev_if = loc->if_idx; + -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, ++ ret = kernel_bind(sock, (struct sockaddr *)&sockaddr, + sizeof(struct sockaddr_in6)); + if (ret < 0) { + net_err_ratelimited("%s: token %#x bind() to %pI6 index %d failed, error %d\n", + __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin6_addr, loc->if_idx, ret); ++ &sockaddr.sin6_addr, loc->if_idx, ret); + goto error; + } + -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin6_addr, -+ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, -+ ntohs(rem_in.sin6_port), loc->if_idx); -+ + if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) + tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); + -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, ++ sockaddr.sin6_family = AF_INET6; ++ if (rem->port) ++ sockaddr.sin6_port = rem->port; ++ else ++ sockaddr.sin6_port = inet_sk(meta_sk)->inet_dport; ++ sockaddr.sin6_addr = rem->addr; ++ ++ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", ++ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, ++ tp->mptcp->path_index, &loc->addr, ++ ntohs(sport), &sockaddr.sin6_addr, ++ ntohs(sockaddr.sin6_port), loc->if_idx); ++ ++ ret = kernel_connect(sock, (struct sockaddr *)&sockaddr, + sizeof(struct sockaddr_in6), O_NONBLOCK); + if (ret < 0 && ret != -EINPROGRESS) { + net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", @@ -20232,10 +20180,10 @@ index 000000000000..161a63f336d7 +MODULE_VERSION("0.1"); diff --git a/net/mptcp/mptcp_output.c b/net/mptcp/mptcp_output.c new file mode 100644 -index 000000000000..8bf9eb4724fb +index 000000000000..a8a5787adbf1 --- /dev/null +++ b/net/mptcp/mptcp_output.c -@@ -0,0 +1,2008 @@ +@@ -0,0 +1,2015 @@ +/* + * MPTCP implementation - Sending side + * @@ -20868,6 +20816,13 @@ index 000000000000..8bf9eb4724fb + if (!tp->mptcp->fully_established) { + tp->mptcp->second_packet = 1; + tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; ++ if (mptcp_is_data_fin(skb)) { ++ /* If this is a data-fin, do not account for it. Because, ++ * a data-fin does not consume space in the subflow ++ * sequence number space. ++ */ ++ tp->mptcp->last_end_data_seq--; ++ } + } + + return true;