Setup Multipath TCP

Iheb Zannina
5 min readMar 22, 2023

--

Abstract

MPTCP, or Multipath TCP, is important because it addresses some of the limitations of traditional TCP connections. TCP is a widely used protocol for reliable data transfer over the internet. However, it is designed to operate over a single network path, which can lead to problems when there is congestion or failure on that path. In such cases, TCP can experience long delays, timeouts, and retransmissions, which can degrade the performance of the connection.

MPTCP can also distribute the load across multiple paths, which can help prevent congestion and improve the overall performance of the connection. MPTCP not only increases robustness during time of
path failure, but also potentially achieves higher end-to-end throughput.

Notice: The Nay, Nay, Nay nightmare

Please note, that MPTCPv1 is not compatible with MPTCPv0. Therefore, don’t ever try to test this demo with the official MPTCP website, unfortunately the website is linked to an out-of-tree MPTCP kernel.

Not mentioned in the documentation, that’s why i am telling you that. Honestly, I spent a lot of time looping around to just verify if my MPTCP working good (No traffic blocking). In the website it says you need to type
"curl https://multipath-tcp.org" , sounds easy hah. Indeed, somehow I got this:

$ curl https://multipath-tcp.org
Nay, Nay, Nay, your have an old computer that does not speak MPTCP.
Shame on you!

The shame is not on you my friend, it is on them. No need to worry, you are running a better version, they can’t understand you.

However, if you would verify if your MPTCP is enabled, just type

$ sudo sysctl net.mptcp.enabled
net.mptcp.enabled = 1

Of course you can affect to this variable either (0 or 1). 1 means true , 0 means false. As we said, the Linux kernel above 5.6 already implements MPTCPv1, so it should be 1 by default and you are ready to go.

Getting started

Prerequisites

The following packages needs to be installed on your system:

Scenario

During this test, I am going to use 2 Ubuntu laptops running the V5.15 Linux kernel. One laptop will work as a client and the other one as a server.

Configure routing

You can do it manually (very cumbersome) ← Not recommended
Or skip to the best part: ← Recommended : Configure this in both laptops

Place this script inside /etc/network/if-up.d/ and make it executable. (Name the file: mptcp_up)

Also, place this script inside /etc/network/if-post-down.d/ and make it executable. (Name the file: mptcp_down)

If your laptops are linked to each other through your LAN network, then you don’t need these steps. The DHCP server gonna serve you. The main thing is that your laptops can ping each others.

Server configuration

Set the total number of allowed sub-flows (whether they are initiated locally or by the peer) to 1. 1 because In our case, we need just another one sub-flow for the WLAN interface. This max number limit, depends on how much interfaces (a.k.a sub-flows) you gonna use besides your default interface.

$ sudo ip mptcp limits set subflow 1

Allow the In_kernel path manager to initiate a new sub-flow using <WLAN> interface as source address

$ sudo ip mptcp endpoint add <WLAN ip address> dev <interface name> subflow 
signal

#You can verify with:

$ sudo ip mptcp limit show

Now, for the testing, what we can do, is run iperf3 as a server (lisning on 5201 port), and in the other hand, we can use the (iperf3 -c) as a client in the client laptop to send packets to the server. Or, we can use python to start a web server (listen on 8000 port) in our server, and from the other client laptop, we can access to this server, and download a big file with the WGET command. Both solutions are enough for our tests.
For me I prefer the first one (More reconfigurable).

# MPTCPIZE used to force the application to use MPTCP at the socket 
communication.
$ sudo mptcpize run python -m http.server 8000 //gonna create like a local web server where you can find your local files
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...


# Or start iperf3 server
$ sudo mptcpize run iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

And of course to verify if MPTCP works we can use

$ sudo ip mptcp monitor
#or test if the connection is using MPTCP
$ tcpdump -n -i <interface> tcp | grep mptcp

Client configuration

Set the total number of allowed sub-flows (whether they are initiated locally or by the peer) to 1.

$ sudo ip mptcp limits set subflow 1

For best practice you can also activate the bmon application to monitor the traffic in your interfaces.

$ sudo bmon -b

Now we are done, let’s download some files from our web server.

$ sudo mptcpize run wget 10.22.17.33:8000/Downloads/ubuntu-18.04.6-desktop-amd64.iso
#--2023-03-20 #21:15:55-- http://10.22.17.33:8000/Downloads/ubuntu-18.04.6-desktop-amd64.iso
#Connecting to 10.22.17.33:8000... connected.
#HTTP request sent, awaiting response... 200 OK
#Length: 2514124800 (2,3G) [application/x-iso9660-image]
#Saving to: 'ubuntu-18.04.6-desktop-amd64.iso.32'
#o.32 36%[======> ] 882,65M 113MB/s eta 15s

bmon -b shows: Both interfaces are used, and if one goes down the other one still working. In addition, if the interface goes up again it will be used again.

bmon -b: Interfaces monitoring

On the monitoring terminal, ip mptcp monitor now logs:

SF_ESTABLISHED stands for our mptcp join and we can see the tokens exchanged, which are the cryptographic keys in order to add new sub-flow.

--

--