How to Configure Linux Multipath TCP (MPTCP) for Seamless Wi-Fi to Cellular Handovers

The Transmission Control Protocol (TCP) was designed in the 1970s with a fundamental assumption: a connection exists between exactly one source IP address and one destination IP address. If your smartphone is downloading a large file over Wi-Fi, and you walk out of your front door, the Wi-Fi drops. The smartphone switches to its 5G cellular interface (which has a completely different IP address). Because the IP address changed, the original TCP socket collapses. The download fails, the video stream buffers, and the SSH session freezes.

Multipath TCP (MPTCP), standardized in RFC 8684, solves this profound architectural flaw. MPTCP allows a single logical TCP connection to be fragmented across multiple physical network interfaces simultaneously.

If you are connected to both Wi-Fi and 5G, MPTCP aggregates the bandwidth of both links. More importantly, if the Wi-Fi connection drops entirely, the MPTCP connection seamlessly survives the outage, routing all packets instantly over the remaining 5G link without breaking the application-layer socket. The video stream never stutters.

This guide explains how to enable and configure Multipath TCP in the Linux kernel.

Understanding the MPTCP Architecture

MPTCP functions as a shim layer located exactly between the standard TCP stack and the application layer.

  1. The Master Connection: The client initiates a standard TCP SYN handshake, but injects a special MP_CAPABLE option into the header. If the server supports MPTCP, it replies with MP_CAPABLE. The initial connection is established over the first available route (e.g., Wi-Fi).
  2. Subflows: The client’s MPTCP daemon detects that a second network interface (e.g., an LTE modem) is available. It initiates a new, separate TCP connection (a “subflow”) from the LTE IP address to the server, injecting an MP_JOIN option.
  3. The Aggregation: The application (like a web browser or SSH client) only sees one continuous socket. Under the hood, the Linux kernel slices the application’s data payload, distributing the packets dynamically across the Wi-Fi subflow and the LTE subflow based on latency and congestion algorithms.

Step 1: Enabling MPTCP in the Linux Kernel

Multipath TCP has been natively integrated into the mainline Linux kernel since version 5.6.

First, verify that your current kernel was compiled with MPTCP support:

zgrep CONFIG_MPTCP /proc/config.gz

You should see CONFIG_MPTCP=y and CONFIG_MPTCP_IPV6=y. If your distribution (like older Ubuntu LTS versions) does not support it natively, you must upgrade your kernel.

Next, enable the MPTCP protocol via sysctl:

sudo sysctl -w net.mptcp.mptcp_enabled=1

To make this persistent across reboots:

echo "net.mptcp.mptcp_enabled=1" | sudo tee /etc/sysctl.d/99-mptcp.conf

Step 2: Installing the MPTCP Daemon (mptcpd)

While the kernel handles the packet routing, it needs a user-space daemon to monitor network interfaces (like NetworkManager dropping a Wi-Fi connection) and instruct the kernel to establish or tear down subflows.

Install the mptcpd daemon (on Ubuntu/Debian):

sudo apt-get update
sudo apt-get install mptcpd

Start and enable the service:

sudo systemctl enable --now mptcpd

Step 3: Configuring the Path Manager

The Linux kernel uses a “Path Manager” to determine how subflows behave. The default path manager is usually set to handle basic failover, but we must explicitly define the network endpoints.

Assume your Linux machine has two interfaces: eth0 (primary wired/Wi-Fi) and eth1 (backup cellular/second ISP). We use the ip mptcp command to configure the routing.

Declare eth1 as an MPTCP endpoint and instruct the kernel that it should be used as a “backup” link (only utilized if eth0 fails):

sudo ip mptcp endpoint add dev eth1 backup

Alternatively, if you want to actively bond the connections together for maximum aggregated bandwidth (using both links simultaneously), omit the backup flag:

sudo ip mptcp endpoint add dev eth1 signal

Step 4: Forcing Applications to Use MPTCP

Here is the catch: For MPTCP to work, the application code (e.g., Python, C++, NGINX) must explicitly request the IPPROTO_MPTCP protocol when calling the socket() function. Most legacy applications still hardcode IPPROTO_TCP.

To force legacy applications to use MPTCP without rewriting their source code, you can use the mptcpize utility, which uses LD_PRELOAD to dynamically intercept the socket calls.

For example, to run an iperf3 bandwidth test utilizing MPTCP over all available interfaces:

mptcpize run iperf3 -c server.example.com

(Note: The server at server.example.com MUST also be running a Linux kernel with MPTCP enabled. Apple’s iOS enables MPTCP by default for Siri and Apple Music, but Linux servers require explicit configuration).

Step 5: Verifying Subflows

While the connection is active, you can monitor the kernel’s active MPTCP sockets and subflows using the ss command.

ss -tin | grep -i mptcp

You will see the master MPTCP connection state, and if you disrupt the primary interface (e.g., sudo ip link set eth0 down), the ss output will instantly reflect the traffic migrating exclusively to the eth1 subflow, all while the iperf3 transfer continues uninterrupted.

Conclusion

Multipath TCP represents a generational leap in network reliability. By decoupling the TCP socket from the physical IP address, network engineers can achieve zero-packet-loss failover between completely disparate network mediums (Wi-Fi, 5G, Satellite). Whether deploying high-availability load balancers or ensuring unbreakable connectivity for mobile robotics, configuring MPTCP in the Linux kernel is essential for modern, fault-tolerant networking.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.