Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mptcp: add a new sysctl for make after break timeout

The MPTCP protocol allows sockets with no alive subflows to stay
in ESTABLISHED status for and user-defined timeout, to allow for
later subflows creation.

Currently such timeout is constant - TCP_TIMEWAIT_LEN. Let the
user-space configure them via a newly added sysctl, to better cope
with busy servers and simplify (make them faster) the relevant
pktdrill tests.

Note that the new know does not apply to orphaned MPTCP socket
waiting for the data_fin handshake completion: they always wait
TCP_TIMEWAIT_LEN.

Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20231023-send-net-next-20231023-2-v1-1-9dc60939d371@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Paolo Abeni and committed by
Jakub Kicinski
d866ae9a aad36cd3

+31 -3
+11
Documentation/networking/mptcp-sysctl.rst
··· 25 25 26 26 Default: 120 27 27 28 + close_timeout - INTEGER (seconds) 29 + Set the make-after-break timeout: in absence of any close or 30 + shutdown syscall, MPTCP sockets will maintain the status 31 + unchanged for such time, after the last subflow removal, before 32 + moving to TCP_CLOSE. 33 + 34 + The default value matches TCP_TIMEWAIT_LEN. This is a per-namespace 35 + sysctl. 36 + 37 + Default: 60 38 + 28 39 checksum_enabled - BOOLEAN 29 40 Control whether DSS checksum can be enabled. 30 41
+16
net/mptcp/ctrl.c
··· 27 27 #endif 28 28 29 29 unsigned int add_addr_timeout; 30 + unsigned int close_timeout; 30 31 unsigned int stale_loss_cnt; 31 32 u8 mptcp_enabled; 32 33 u8 checksum_enabled; ··· 66 65 return mptcp_get_pernet(net)->stale_loss_cnt; 67 66 } 68 67 68 + unsigned int mptcp_close_timeout(const struct sock *sk) 69 + { 70 + if (sock_flag(sk, SOCK_DEAD)) 71 + return TCP_TIMEWAIT_LEN; 72 + return mptcp_get_pernet(sock_net(sk))->close_timeout; 73 + } 74 + 69 75 int mptcp_get_pm_type(const struct net *net) 70 76 { 71 77 return mptcp_get_pernet(net)->pm_type; ··· 87 79 { 88 80 pernet->mptcp_enabled = 1; 89 81 pernet->add_addr_timeout = TCP_RTO_MAX; 82 + pernet->close_timeout = TCP_TIMEWAIT_LEN; 90 83 pernet->checksum_enabled = 0; 91 84 pernet->allow_join_initial_addr_port = 1; 92 85 pernet->stale_loss_cnt = 4; ··· 150 141 .mode = 0644, 151 142 .proc_handler = proc_dostring, 152 143 }, 144 + { 145 + .procname = "close_timeout", 146 + .maxlen = sizeof(unsigned int), 147 + .mode = 0644, 148 + .proc_handler = proc_dointvec_jiffies, 149 + }, 153 150 {} 154 151 }; 155 152 ··· 178 163 table[4].data = &pernet->stale_loss_cnt; 179 164 table[5].data = &pernet->pm_type; 180 165 table[6].data = &pernet->scheduler; 166 + table[7].data = &pernet->close_timeout; 181 167 182 168 hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table, 183 169 ARRAY_SIZE(mptcp_sysctl_table));
+3 -3
net/mptcp/protocol.c
··· 2391 2391 if (msk->in_accept_queue && msk->first == ssk && 2392 2392 (sock_flag(sk, SOCK_DEAD) || sock_flag(ssk, SOCK_DEAD))) { 2393 2393 /* ensure later check in mptcp_worker() will dispose the msk */ 2394 - mptcp_set_close_tout(sk, tcp_jiffies32 - (TCP_TIMEWAIT_LEN + 1)); 2395 2394 sock_set_flag(sk, SOCK_DEAD); 2395 + mptcp_set_close_tout(sk, tcp_jiffies32 - (mptcp_close_timeout(sk) + 1)); 2396 2396 lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); 2397 2397 mptcp_subflow_drop_ctx(ssk); 2398 2398 goto out_release; ··· 2516 2516 return false; 2517 2517 2518 2518 return time_after32(tcp_jiffies32, 2519 - inet_csk(sk)->icsk_mtup.probe_timestamp + TCP_TIMEWAIT_LEN); 2519 + inet_csk(sk)->icsk_mtup.probe_timestamp + mptcp_close_timeout(sk)); 2520 2520 } 2521 2521 2522 2522 static void mptcp_check_fastclose(struct mptcp_sock *msk) ··· 2659 2659 return; 2660 2660 2661 2661 close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + 2662 - TCP_TIMEWAIT_LEN; 2662 + mptcp_close_timeout(sk); 2663 2663 2664 2664 /* the close timeout takes precedence on the fail one, and here at least one of 2665 2665 * them is active
+1
net/mptcp/protocol.h
··· 615 615 int mptcp_is_checksum_enabled(const struct net *net); 616 616 int mptcp_allow_join_id0(const struct net *net); 617 617 unsigned int mptcp_stale_loss_cnt(const struct net *net); 618 + unsigned int mptcp_close_timeout(const struct sock *sk); 618 619 int mptcp_get_pm_type(const struct net *net); 619 620 const char *mptcp_get_scheduler(const struct net *net); 620 621 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,