Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension
that enables a TCP connection to use different paths. It allows a device
to make use of multiple interfaces at once to send and receive TCP
packets over a single MPTCP connection. MPTCP can aggregate the
bandwidth of multiple interfaces or prefer the one with the lowest
latency, it also allows a fail-over if one path is down, and the traffic
is seamlessly re-injected on other paths.
To benefit from MPTCP, both the client and the server have to support
it. Multipath TCP is a backward-compatible TCP extension that is enabled
by default on recent Linux distributions (Debian, Ubuntu, Redhat, ...).
Multipath TCP is included in the Linux kernel since version 5.6 [2]. To
use it on Linux, an application must explicitly enable it when creating
the socket:
int sd = socket(AF_INET(6), SOCK_STREAM, IPPROTO_MPTCP);
No need to change anything else in the application.
This patch allows MPTCP protocol in the Socket unit configuration. So
now, a <unit>.socket can contain this to use MPTCP instead of TCP:
[Socket]
SocketProtocol=mptcp
MPTCP support has been allowed similarly to what has been already done
to allow SCTP: just one line in core/socket.c, a very simple addition
thanks to the flexible architecture already in place.
On top of that, IPPROTO_MPTCP has also been added in the list of allowed
protocols in two other places, and in the doc. It has also been added to
the missing_network.h file, for systems with an old libc -- note that it
was also required to include <netinet/in.h> in this file to avoid
redefinition errors.
Link: https://www.rfc-editor.org/rfc/rfc8684.html
Link: https://www.mptcp.dev
<varlistentry>
<term><varname>SocketProtocol=</varname></term>
- <listitem><para>Takes one of <option>udplite</option>
- or <option>sctp</option>. The socket will use the UDP-Lite
- (<constant>IPPROTO_UDPLITE</constant>) or SCTP
- (<constant>IPPROTO_SCTP</constant>) protocol, respectively.</para>
+ <listitem><para>Takes one of <option>udplite</option>,
+ <option>sctp</option> or <option>mptcp</option>. The socket will use
+ the UDP-Lite (<constant>IPPROTO_UDPLITE</constant>), SCTP
+ (<constant>IPPROTO_SCTP</constant>) or MPTCP
+ (<constant>IPPROTO_MPTCP</constant>) protocol, respectively.</para>
<xi:include href="version-info.xml" xpointer="v229"/>
</listitem>
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <netinet/in.h>
+
/* linux/in6.h or netinet/in.h */
#ifndef IPV6_UNICAST_IF
#define IPV6_UNICAST_IF 76
#define IPV6_TRANSPARENT 75
#endif
+/* linux/in.h or netinet/in.h */
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+
/* Not exposed but defined at include/net/ip.h */
#ifndef IPV4_MIN_MTU
#define IPV4_MIN_MTU 68
if (i == IPPROTO_IP)
return "";
- if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP))
+ if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP, IPPROTO_MPTCP))
return NULL;
return ip_protocol_to_name(i);
r = parse_ip_protocol(s);
if (r < 0)
return r;
- if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP))
+ if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP, IPPROTO_MPTCP))
return -EPROTONOSUPPORT;
return r;
switch (p->address.type) {
case SOCK_STREAM:
+ if (IN_SET(s->socket_protocol, IPPROTO_SCTP, IPPROTO_MPTCP))
+ p->address.protocol = s->socket_protocol;
+ break;
+
case SOCK_SEQPACKET:
if (s->socket_protocol == IPPROTO_SCTP)
p->address.protocol = s->socket_protocol;
TEST(parse_ip_protocol) {
assert_se(parse_ip_protocol("sctp") == IPPROTO_SCTP);
assert_se(parse_ip_protocol("ScTp") == IPPROTO_SCTP);
+ assert_se(parse_ip_protocol("mptcp") == IPPROTO_MPTCP);
+ assert_se(parse_ip_protocol("MPTCP") == IPPROTO_MPTCP);
assert_se(parse_ip_protocol("ip") == IPPROTO_IP);
assert_se(parse_ip_protocol("") == IPPROTO_IP);
assert_se(parse_ip_protocol("1") == 1);
ListenUSBFunction=
SocketProtocol=udplite
SocketProtocol=sctp
+SocketProtocol=mptcp
SocketProtocol=
BindIPv6Only=false
Backlog=33