summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorKrister Johansen <kjlx@templeofstupid.com>2025-09-08 11:16:01 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-09-19 16:29:56 +0200
commit6f3b2d8034241e5de0162a60845f8b59d69f8afb (patch)
treef3902918cf409033ee02e65aa90e6fbb1567957c /net
parent17b41ca55cea572d5af0c1178b65a3ac6a623cef (diff)
downloadlinux-6f3b2d8034241e5de0162a60845f8b59d69f8afb.tar.gz
linux-6f3b2d8034241e5de0162a60845f8b59d69f8afb.tar.bz2
linux-6f3b2d8034241e5de0162a60845f8b59d69f8afb.zip
mptcp: sockopt: make sync_socket_options propagate SOCK_KEEPOPEN
commit 648de37416b301f046f62f1b65715c7fa8ebaa67 upstream. Users reported a scenario where MPTCP connections that were configured with SO_KEEPALIVE prior to connect would fail to enable their keepalives if MTPCP fell back to TCP mode. After investigating, this affects keepalives for any connection where sync_socket_options is called on a socket that is in the closed or listening state. Joins are handled properly. For connects, sync_socket_options is called when the socket is still in the closed state. The tcp_set_keepalive() function does not act on sockets that are closed or listening, hence keepalive is not immediately enabled. Since the SO_KEEPOPEN flag is absent, it is not enabled later in the connect sequence via tcp_finish_connect. Setting the keepalive via sockopt after connect does work, but would not address any subsequently created flows. Fortunately, the fix here is straight-forward: set SOCK_KEEPOPEN on the subflow when calling sync_socket_options. The fix was valdidated both by using tcpdump to observe keepalive packets not being sent before the fix, and being sent after the fix. It was also possible to observe via ss that the keepalive timer was not enabled on these sockets before the fix, but was enabled afterwards. Fixes: 1b3e7ede1365 ("mptcp: setsockopt: handle SO_KEEPALIVE and SO_PRIORITY") Cc: stable@vger.kernel.org Signed-off-by: Krister Johansen <kjlx@templeofstupid.com> Reviewed-by: Geliang Tang <geliang@kernel.org> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/aL8dYfPZrwedCIh9@templeofstupid.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/mptcp/sockopt.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 129c9e9ee396..341fca0a4bf4 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1347,13 +1347,12 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
{
static const unsigned int tx_rx_locks = SOCK_RCVBUF_LOCK | SOCK_SNDBUF_LOCK;
struct sock *sk = (struct sock *)msk;
+ bool keep_open;
- if (ssk->sk_prot->keepalive) {
- if (sock_flag(sk, SOCK_KEEPOPEN))
- ssk->sk_prot->keepalive(ssk, 1);
- else
- ssk->sk_prot->keepalive(ssk, 0);
- }
+ keep_open = sock_flag(sk, SOCK_KEEPOPEN);
+ if (ssk->sk_prot->keepalive)
+ ssk->sk_prot->keepalive(ssk, keep_open);
+ sock_valbool_flag(ssk, SOCK_KEEPOPEN, keep_open);
ssk->sk_priority = sk->sk_priority;
ssk->sk_bound_dev_if = sk->sk_bound_dev_if;