MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Multipath TCP (MPTCP) is one of the most valuable networking capabilities in the Linux kernel in recent years, especially suitable for scenarios such as in-vehicle gateways (T-BOX), parallel driving, and multi-link redundancy. It can simultaneously utilize multiple links such as 4G/5G, Wi-Fi, and Ethernet, significantly enhancing data throughput, link recovery, and disaster recovery capabilities in weak network environments.

However, in practical engineering, the performance of MPTCP in Linux 5.x is far from being as “plug-and-play” as imagined. Especially in high-pressure scenarios such as weak networks, multi-links, NAT, and public networks, the stability and completeness of MPTCP’s functionality are crucial.

Although Linux 5.10 is the first LTS version to include MPTCP, there are still many unresolved defects in engineering practice— including flow drops, inability to recover subflows, connection hangs, address mapping failures, and abnormal subflow establishment in NAT environments. After multiple validations in our projects, we found that MPTCP in Linux 5.10 is more like “it can run, but it is not suitable for production environments.”

In contrast, Linux 5.15 truly becomes the first “engineering usable version” of the MPTCP kernel. In this version, the community has merged a large number of fix patches and capability enhancements, which not only significantly improve stability and functional consistency but also allow the subflow mode to truly reach a level that can run stably in actual projects.

Based on our practical experience in in-vehicle networks, parallel driving, and real-time services in weak networks: MPTCP in Linux 5.10 does not meet mass production conditions, while MPTCP in Linux 5.15 has stable engineering value for deployment.

1Why pay attention to Linux MPTCP?

Simply put, MPTCP allows:

  • A single connection to use multiple network interfaces (WiFi + cellular / dual cellular + Ethernet)

  • Business to be transparent to network switching

  • Weak networks to be more reliable

  • Multi-links to aggregate bandwidth

  • Automatic failover during sudden changes in network quality

This capability is critical for scenarios such as in-vehicle gateways, unmanned delivery, cloud control systems, and edge nodes. However, it also places higher demands on the implementation quality of the Linux kernel.

2MPTCP in Linux 5.10 Kernel: Incomplete Functionality, Engineering UnusableLinux 5.10 is the first long-term support (LTS) version to include MPTCP, but it is more like a “basic model”:

2.1

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Subflow implementation is incomplete

  • Subflow establishment/closure processes are prone to race conditions

  • Multiple subflows are prone to out-of-order, deadlock, and DATA_FIN blockage in weak network scenarios

  • Join subflow fails with high probability in NAT environments

  • Cannot correctly recover subflows after abnormal disconnections

Engineering practice conclusion: Unable to stably establish subflows, let alone recover in weak networks.

2.2

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Path Manager functionality is limited

Linux 5.10’s PM (Path Manager) has multiple defects:

  • fullmesh mode is unavailable

  • Address synchronization (ADD_ADDR/RM_ADDR) logic defects

  • Interface up/down events cannot correctly trigger reconnections

  • mptcpd has limited compatibility on Linux 5.10, basically unusable

Result: A device that seems to have multiple links actually only maintains one link operational.

2.3

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Scheduler behavior is rudimentary

The default scheduling policy in Linux 5.10 cannot guarantee stable throughput in:

  • Asymmetric RTT scenarios of WiFi + cellular

  • High packet loss scenarios

  • Links with significant bandwidth differences

It may even lead to connection hangs.

2.4

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Serious bugs in DSS

  • DATA_FIN cannot be successfully sent or received

  • Retransmission mapping errors

  • Confused skb_mapping leads to read/write hangs

These issues are particularly evident in continuous weak networks (e.g., in-vehicle cellular).

2.5

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Poor NAT/firewall compatibility

MPTCP in Linux 5.10 fails significantly in the following environments:

  • Multi-level NAT

  • Carrier NAT

  • Wireless gateways

  • VPN + NAT scenarios

Engineering result: Subflows cannot join, and MPTCP degrades to ordinary TCP.

2.6

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Insufficient stability

Under stress testing:

  • Connections may hang

  • Subflows may remain in half-closed state indefinitely

  • Retry mechanisms are inadequate

3Upgrading MPTCP stack from Linux 5.10 to Linux 5.15

In actual projects, if conditions permit, the most recommended solution is always to directly upgrade the system kernel to Linux 5.15 or higher, and regularly follow up on minor version updates according to the LTS lifecycle (refer to the official maintenance plan: kernel.org). This is the best way to obtain stable and complete MPTCP capabilities.

However, in many in-vehicle projects, custom BSPs, SoC closed SDKs, or commercial distributions, the kernel version is often locked at Linux 5.10, making it impossible to upgrade the entire system. In this case, a feasible engineering solution that we have validated on a large scale is:

To upgrade the entire MPTCP stack to the Linux 5.15 version while keeping the Linux 5.10 kernel framework unchanged.

We have validated the feasibility of this solution in over 100 terminals, accumulating over 300,000 hours of real-world testing, and its stability performance is completely consistent with the native Linux 5.15 kernel. As long as the MPTCP subsystem of 5.15 is merged correctly and 3 to 5 simple conflict patches are handled well, it is possible to achieve the same MPTCP stability as Linux 5.15 without upgrading the entire kernel.

Below, we will provide a set of executable guidance to help engineering teams safely and controllably upgrade MPTCP from 5.10 to 5.15 to meet the actual needs in in-vehicle networks and weak network environments.

3.1

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Download LTS code

git clone https://github.com/gregkh/linux.git

3.2

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Extract MPTCP-related changes

My project is Linux 5.10.66, and I upgraded to Linux 5.15.162. The specific extraction script is as follows, based on this script you will be able to extract about 431 patches.

#!/bin/bash# Get relevant commit logsgit fetch origin v5.15.162echo "git fetch ok"# Filter all commit hashes between v5.10.66 and v5.15.162 in chronological ordergit log v5.10.66..v5.15.162 --pretty=format:"%H" --reverse > all.logecho "git log ok"# Create directory to save patchesmkdir -p mptcp_patches# Initialize patch numberpatch_number=1# Iterate through each commit hashwhile read commit_hash; do    # Get the list of files modified in the commit    files=$(git diff-tree --no-commit-id --name-only -r $commit_hash)    # Check if net/mptcp was modified    if echo "$files" | grep -q "net/mptcp"; then        # Get commit summary        commit_subject=$(git show -s --format=%s $commit_hash)        # Remove spaces and special characters from summary        commit_subject_clean=$(echo $commit_subject | tr -d '[:punct:]' | tr ' ' '_')        # Generate patch file, using commit hash to generate file        git format-patch -1 $commit_hash -o mptcp_patches        # Get the name of the newly generated patch file        latest_patch=$(ls -t mptcp_patches | head -n 1)        # Rename patch file, adding number and summary        patch_filename=$(printf "mptcp_patches/%04d-%s-%s.patch" $patch_number $commit_hash $commit_subject_clean)        mv "mptcp_patches/$latest_patch" "$patch_filename"        echo "$patch_filename"        patch_number=$((patch_number + 1))    fidone < all.log# Clean up log filerm -f all.logecho "Patch generation completed, saved in mptcp_patches directory."

3.3

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Do not merge SO_TIMESTAMP settings

The following patches do not need to be merged directly, but inform you to handle similarly when compilation fails, by removing this feature.

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.cindex c7cfd9818f8f..0fd47259e1d5 100644--- a/net/ipv4/tcp.c+++ b/net/ipv4/tcp.c@@ -2511,7 +2511,8 @@ void __tcp_close(struct sock *sk, long timeout)  /* remove backlog if any, without releasing ownership. */  __release_sock(sk);- this_cpu_inc(tcp_orphan_count);+ // TODO jeff+ percpu_counter_inc(sk->sk_prot->orphan_count);  /* Have we already been destroyed by a softirq or backlog? */  if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE)diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.cindex 565384a7f062..5a702b895afe 100644--- a/net/mptcp/sockopt.c+++ b/net/mptcp/sockopt.c@@ -142,27 +142,8 @@ static void mptcp_so_incoming_cpu(struct mptcp_sock *msk, int val) static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optname, int val) {- sockptr_t optval = KERNEL_SOCKPTR(&>val);- struct mptcp_subflow_context *subflow;- struct sock *sk = (struct sock *)msk;- int ret;-- ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname,- optval, sizeof(val));- if (ret)- return ret;-- lock_sock(sk);- mptcp_for_each_subflow(msk, subflow) {- struct sock *ssk = mptcp_subflow_tcp_sock(subflow);- bool slow = lock_sock_fast(ssk);-- sock_set_timestamp(sk, optname, !!val);- unlock_sock_fast(ssk, slow);- }-- release_sock(sk);- return 0;+ pr_debug("msk=%p. SO_TIMESTAMP-xxx no support", msk);+ return -ESOCKTNOSUPPORT; } static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,@@ -203,32 +184,8 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, sockptr_t optval, unsigned int optlen) {- struct mptcp_subflow_context *subflow;- struct sock *sk = (struct sock *)msk;- int val, ret;-- ret = mptcp_get_int_option(msk, optval, optlen, &>val);- if (ret)- return ret;-- ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname,- KERNEL_SOCKPTR(&>val), sizeof(val));- if (ret)- return ret;-- lock_sock(sk);-- mptcp_for_each_subflow(msk, subflow) {- struct sock *ssk = mptcp_subflow_tcp_sock(subflow);- bool slow = lock_sock_fast(ssk);-- sock_set_timestamping(sk, optname, val);- unlock_sock_fast(ssk, slow);- }-- release_sock(sk);-- return 0;+ pr_debug("msk=%p. SO_TIMESTAMP-xxx no support", msk);+ return -ESOCKTNOSUPPORT; } static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t optval,@@ -329,8 +286,6 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, case SO_RCVTIMEO_OLD: case SO_RCVTIMEO_NEW: case SO_BUSY_POLL:- case SO_PREFER_BUSY_POLL:- case SO_BUSY_POLL_BUDGET: /* No need to copy: only relevant for msk */ return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen); case SO_NO_CHECK:

3.4

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Additional merging of two patches

Execute these two commands in the directory of the downloaded Linux LTS code from section 3.1.

git show 049fe386d35353398eee40ba8d76ab62cb5a24e5git show 2dcb96bacce36021c2f3eaae0cef607b5bb71ede

4Improvement points for MPTCP in Linux 5.15

  • Linux 5.15 does not fully support Fullmesh path management mode.

  • Linux 5.15 does not support redundant scheduling mode. If you expect to implement the multi-send single-receive mode of mptcpV0, you need to merge a non-mainline version of the MPTCP eBPF scheduler.

MPTCP: Engineering Practice Summary from Linux 5.10 to 5.15

Leave a Comment