Skip to content
LinuxDeep Dive Published Updated 9 min readViews unavailable

Linux MPTCP: Path Managers, Subflows, and Failover

Configure Linux MPTCP endpoints and subflows, distinguish kernel and userspace path managers, diagnose TCP fallback, and test real failover.

Multipath TCP (MPTCP) extends TCP so one logical connection can use multiple network paths. On Linux, an application opts in by creating a socket with IPPROTO_MPTCP; the kernel starts with a TCP subflow and can negotiate additional subflows with a peer. With suitable addresses, routing, peer support, and policy, this can preserve a connection across a path loss or use more than one path. It does not turn two interfaces into a generic bonded link, guarantee aggregate bandwidth, or encrypt traffic.

The useful operational model has four pieces: the application requests MPTCP, a path manager decides which addresses and subflows to create, the packet scheduler chooses where to send data, and ordinary routing/firewall policy must make each path work. Diagnosing only the interface configuration misses most failure modes.

An MPTCP connection is identified as one transport-level connection to the application, but its data can travel over one or more TCP subflows. Each subflow is a regular TCP connection with MPTCP signaling. The peers negotiate support during connection setup. If the remote endpoint or a middlebox does not accept the MPTCP option, Linux can downgrade that connection to ordinary TCP and continue on one path. A successful socket() call therefore proves that the local kernel accepted the request; it does not prove that the established connection is using MPTCP.

Keep these mechanisms distinct:

Mechanism What it controls What it does not establish
MPTCP path manager Address announcements and subflow creation/removal for an MPTCP connection. That the host’s routing table, firewall, NAT, or peer will permit each path.
MPTCP packet scheduler Which available subflow carries the next data. A fixed ordering, a real-time deadline, or guaranteed bandwidth aggregation.
Policy routing Which route/table is selected for traffic matching routing policy. MPTCP negotiation or subflow creation by itself.
Ethernet bonding Link-level aggregation/failover for an interface configuration. A single MPTCP transport connection across independent IP paths.

MPTCP is standardized by RFC 8684, while Linux’s IPPROTO_MPTCP, sysctls, path-manager controls, and ip mptcp commands are implementation interfaces. Check both the protocol peer and the exact kernel/userspace versions on the machines you operate.

Confirm the application and kernel actually request MPTCP

Linux applications opt in when opening the socket. The kernel documentation identifies the protocol number as 262 and describes errors for kernels without MPTCP support or where the feature is disabled. Applications that keep using IPPROTO_TCP do not automatically gain MPTCP merely because the host has multiple interfaces.

#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>

int main(void) {
    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
    if (fd == -1) {
        perror("socket(IPPROTO_MPTCP)");
        return EXIT_FAILURE;
    }

    /* Connect/bind and use fd as a stream socket; close it in real code. */
    return EXIT_SUCCESS;
}

This is only the socket-creation step, not a complete client. Header availability can lag the kernel, so compile against the target distribution’s development headers instead of assuming every libc toolchain defines IPPROTO_MPTCP. If the code builds but the call fails, record errno and inspect the target kernel’s MPTCP configuration and namespace-specific net.mptcp.enabled setting. Current kernel documentation distinguishes an unavailable protocol, a kernel compiled without MPTCP, and MPTCP disabled by sysctl; the exact error depends on the failure condition and kernel version.

For a controlled environment, check the namespace in which the application runs:

sysctl net.mptcp.enabled
sysctl net.mptcp.path_manager
ip mptcp endpoint show
ip mptcp limits show

These commands inspect the current network namespace. A container or test namespace can have different MPTCP sysctl and endpoint state than the host. Do not infer container behavior from a host-level command run in another namespace. Older kernels and iproute2 builds may expose a different set of controls; confirm command support with the installed ip mptcp help and the matching kernel documentation.

Choose the path manager before adding endpoints

The in-kernel path manager applies shared rules to new MPTCP connections. The userspace path manager delegates per-connection address and subflow decisions to a privileged userspace program such as mptcpd, using the MPTCP Netlink API. That choice changes where policy lives: kernel-managed endpoint configuration is straightforward for a common host policy, while userspace management is useful when decisions depend on each connection or an operator’s control plane.

The net.mptcp.path_manager sysctl is per network namespace. The older net.mptcp.pm_type integer is deprecated since Linux 6.15 in the current documentation; prefer the named path_manager control on supported kernels and verify the target version before scripting a migration. Do not set both as if they were independent features. A userspace manager also adds a privileged daemon and Netlink event/control path that need their own lifecycle, logs, restart behavior, and access controls.

The path manager and packet scheduler solve different questions. The manager creates or removes subflows; the scheduler selects an already available subflow for data. A host can have endpoints configured but still send only on the initial subflow because the peer did not negotiate MPTCP, the endpoint was not announced/accepted, the connection limits were reached, or routing/firewall policy prevents a join.

Configure endpoints with the kernel path manager

The following is an illustrative lab configuration. Replace the documentation-only addresses, interface names, and limits with addresses actually assigned and routed in your test network. Run it only in a disposable namespace or test host with the required privileges; do not paste it into a production shell unchanged.

# Example values only: 192.0.2.0/24 and 198.51.100.0/24 are documentation ranges.
sudo ip mptcp endpoint add 192.0.2.10 dev wan0 id 1 subflow
sudo ip mptcp endpoint add 198.51.100.20 dev lte0 id 2 subflow backup
sudo ip mptcp limits set subflow 2 add_addr_accepted 1

ip mptcp endpoint show
ip mptcp limits show
ip mptcp monitor

An endpoint associates a local address with an MPTCP role. The dev association matters: it ties the address to the intended interface for path-manager use, while normal route selection still needs to reach the peer over that interface. The subflow flag permits the path manager to try an additional subflow using that local source address. A signal endpoint instead advertises an address to the peer with ADD_ADDR; the peer may then try a subflow back to it. These roles are not interchangeable, and neither proves that a remote peer accepts the advertisement.

Use subflow backup together when an endpoint should request an additional path and mark it as backup: subflow requests the subflow, while backup marks the path’s priority and does not create a subflow by itself. With the default scheduler, the backup path is used for outgoing data when non-backup subflows are unavailable; the flag also tells the peer how to treat that subflow. Validate actual behavior with both endpoints and the scheduler in use rather than interpreting “backup” as a guarantee of a particular failover time. The ip mptcp limits values constrain additional subflow creation and accepted address announcements; they are limits, not a promise that all requested paths will be created.

Endpoint IDs are identifiers within the path-manager configuration, not Linux interface indices; the initial subflow uses reserved ID 0, so user-added endpoints need their own unique nonzero IDs. Do not use ip mptcp endpoint flush as routine cleanup on a shared host: it removes all configured MPTCP endpoints in the current namespace. Prefer endpoint show first, then delete only the specific endpoint you are changing.

Test negotiation and failure, not just configuration

Use a test service and a peer you control. First establish a single-path MPTCP-capable connection, then verify that both sides negotiated MPTCP and that the expected subflow events appear. The kernel exposes TCP_IS_MPTCP for checking whether a TCP-level socket is currently using MPTCP; the ip mptcp monitor command reports connection, address, and subflow events. Capture the test’s initial SYN/SYN-ACK as supporting evidence for MPTCP negotiation, but do not substitute a packet capture for the application’s own success/error handling.

Run separate tests for these cases:

  1. Peer without MPTCP or an option-stripping middlebox: confirm the connection continues as ordinary TCP if fallback occurs, and make sure the application still has correct semantics on the single path.
  2. Second path reachable: check route selection, source address, firewall/NAT rules, and whether an additional subflow becomes established. An ADD_ADDR announcement is not proof that a join succeeded.
  3. Primary path loss: remove or block the path only in an isolated test and measure application-visible stall, retransmission, and recovery behavior. Preserve the original interface and routes on production systems.
  4. Restart and namespace lifecycle: restart the userspace path manager or recreate the container/network namespace and verify that endpoints and policy are restored by the service that owns them.

Record the kernel release, iproute2 version, per-namespace sysctls, endpoint/limit output, peer support, routes, and event timeline. That gives a useful comparison when a distribution backports kernel changes without changing its upstream-looking version string.

Treat path announcements and encryption as separate concerns

MPTCP is a transport feature, not confidentiality protection. Use TLS or another authenticated encryption layer when the application requires confidentiality and integrity. Advertised IP addresses can reveal network topology and may be blocked or rewritten by NAT/firewall devices. Announce only addresses intended to be reachable by the peer, and check that the policy remains acceptable when interfaces change.

Do not promise that using multiple paths always improves throughput. A scheduler, congestion control, receiver, route asymmetry, or one slow/lossy path can change performance; middleboxes can prevent negotiation; and an application’s data rate may be limited elsewhere. Measure the real workload against a plain-TCP control and test failover with the peer and network path that will exist in production.

Operational checklist

  • The application explicitly requests IPPROTO_MPTCP, and the deployed kernel supports and enables it in the application’s network namespace.
  • Both peers and any intervening middleboxes have been tested for negotiation and fallback.
  • The selected path manager owns the intended policy; the scheduler is treated as a separate decision.
  • Each endpoint address is assigned, routed, associated with the correct device, and allowed by firewall/NAT policy.
  • Subflow and accepted-address limits are high enough for the design but not set without a connection-count rationale.
  • ip mptcp monitor and application-level telemetry are captured during normal, fallback, path-loss, and manager-restart tests.
  • Address announcements are reviewed for privacy, and TLS remains responsible for application data protection.

MPTCP can make independent IP paths usable by one TCP application connection, but the operational contract spans the application, both peers, path manager, scheduler, and routed network. Treat each as a separately testable layer.

Related:

Sources:

Comments