Skip to content

Commit c084ebd

Browse files
matttbekuba-moo
authored andcommitted
tcp: socket option to check for MPTCP fallback to TCP
A way for an application to know if an MPTCP connection fell back to TCP is to use getsockopt(MPTCP_INFO) and look for errors. The issue with this technique is that the same errors -- EOPNOTSUPP (IPv4) and ENOPROTOOPT (IPv6) -- are returned if there was a fallback, *or* if the kernel doesn't support this socket option. The userspace then has to look at the kernel version to understand what the errors mean. It is not clean, and it doesn't take into account older kernels where the socket option has been backported. A cleaner way would be to expose this info to the TCP socket level. In case of MPTCP socket where no fallback happened, the socket options for the TCP level will be handled in MPTCP code, in mptcp_getsockopt_sol_tcp(). If not, that will be in TCP code, in do_tcp_getsockopt(). So MPTCP simply has to set the value 1, while TCP has to set 0. If the socket option is not supported, one of these two errors will be reported: - EOPNOTSUPP (95 - Operation not supported) for MPTCP sockets - ENOPROTOOPT (92 - Protocol not available) for TCP sockets, e.g. on the socket received after an 'accept()', when the client didn't request to use MPTCP: this socket will be a TCP one, even if the listen socket was an MPTCP one. With this new option, the kernel can return a clear answer to both "Is this kernel new enough to tell me the fallback status?" and "If it is new enough, is it currently a TCP or MPTCP socket?" questions, while not breaking the previous method. Acked-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://lore.kernel.org/r/20240509-upstream-net-next-20240509-mptcp-tcp_is_mptcp-v1-1-f846df999202@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent e6e4357 commit c084ebd

File tree

3 files changed

+7
-0
lines changed

3 files changed

+7
-0
lines changed

include/uapi/linux/tcp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ enum {
135135
#define TCP_AO_GET_KEYS 41 /* List MKT(s) */
136136
#define TCP_AO_REPAIR 42 /* Get/Set SNEs and ISNs */
137137

138+
#define TCP_IS_MPTCP 43 /* Is MPTCP being used? */
139+
138140
#define TCP_REPAIR_ON 1
139141
#define TCP_REPAIR_OFF 0
140142
#define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */

net/ipv4/tcp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4363,6 +4363,9 @@ int do_tcp_getsockopt(struct sock *sk, int level,
43634363

43644364
return err;
43654365
}
4366+
case TCP_IS_MPTCP:
4367+
val = 0;
4368+
break;
43664369
default:
43674370
return -ENOPROTOOPT;
43684371
}

net/mptcp/sockopt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,8 @@ static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
13481348
return mptcp_put_int_option(msk, optval, optlen, msk->nodelay);
13491349
case TCP_NOTSENT_LOWAT:
13501350
return mptcp_put_int_option(msk, optval, optlen, msk->notsent_lowat);
1351+
case TCP_IS_MPTCP:
1352+
return mptcp_put_int_option(msk, optval, optlen, 1);
13511353
}
13521354
return -EOPNOTSUPP;
13531355
}

0 commit comments

Comments
 (0)