Neo, we must find a faster link, connection to the Matrix is congested. Hurry !

Kernel supports a magical module, called bonding

Bonding: methods of combining (aggregating) multiple network connections in parallel in order to increase throughput

This seems to be exactly what I need. I’ve two ISPs , let’s go ahead and connect two of my android devices via USB Tethering and bond both the connections and enter into the matrix!


Bonding joins two physical network connections to the same network into 1 logical connection. [1]

Ahh.. If only it were the old days, I could just plug in multiple RJ45 cables connected to a single network and increase the throughput but the world has now moved to the Internet and so has the Matrix. I must find another way…

Multipath Routing

Multipath routing is the routing technique of using multiple alternative paths through a network, which can yield a variety of benefits such as fault tolerance, increased bandwidth, or improved security.

Appears interesting. Link, try it!

First, let’s connect to a WiFi network and Android USB tethering.

$ ip -br address
lo               UNKNOWN ::1/128
enp1s0           DOWN
wlp2s0           UP    fe80::4ca5:1c7a:25de:4552/64
enp0s20f0u3      UNKNOWN fe80::61f1:5894:3e86:3981/64

Here wlp2s0 denotes my wireless interface (the WiFi) and enp0s20f0u3 denotes my USB tethered android device’s interface.

Every IP Packet needs to be routed in a routing table.

We can view the default routing table as:

$ ip route
default via dev enp0s20f0u3 proto dhcp metric 100
default via dev wlp2s0 proto dhcp metric 600 dev enp0s20f0u3 proto kernel scope link src metric 100 dev wlp2s0 proto kernel scope link src metric 600

The IP address after ‘via’ is the gateway ( say, router’s IP ).

In order to route our packets over two interfaces (USB Tethering and WiFi), declare two new routing tables:

# echo 200 L1 >> /etc/iproute2/rt_tables
# echo 201 L2 >> /etc/iproute2/rt_tables

Numbers 200 and 201 are arbitrary.

Before proceeding, declare some variables according to the above outputs [2]:

$ IF1=wlp2s0
$ IF2=enp0s20f0u3
$ IP1=
$ IP2=
$ P1=
$ P2=
$ P1_NET=
$ P2_NET=

Now, populate the routing tables (actual creation) to contain proper interfaces and gateway IPs

# ip route add $P1_NET dev $IF1 src $IP1 table T1
# ip route add default via $P1 table T1
# ip route add $P2_NET dev $IF2 src $IP2 table T2
# ip route add default via $P2 table T2

Create rules, so that all connections coming on a interface get answered on the same interface. This is important, if a remote server requests some info via WiFi, you cannot just reply via USB Tethered connection and expect everything to work.

# ip rule add from $IP1 table T1
# ip rule add from $IP2 table T2

Now comes the juicy part. To set up a multipath route.

$ ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \
	    nexthop via $P2 dev $IF2 weight 1

Next hop specifies the next router the packet should hop to. Here, two nexthops imply there are two possibilities with the respective weights.


The Machines have written a code to automate all this.
Beware, it’s the machines!

Did it work ?

Verify by running watch curl -s You should be able to see changing IPs per request.


In order to increase download bandwidth, use the awesome tool - aria2 Find out your internet facing interfaces (say $IF1, $IF2) and issue:

aria2c --multiple-interface $IF1,$IF2 https://download.tld/url.ext


1. Internet is slower
The above steps roughly split the amount of packets over two interfaces (connections), if one of the connection is very slow, it would slow down everything. To avoid this, increase the weight for the faster connection.

2. is showing same IP every time in Firefox/Chrome.
The culprit could be cached connections or hell lot of other reasons. To verify it’s working overall, check your IP on multiple websites (duckduckgo, ipecho, iplocation to name a few)

3. Something else ?
Follow the white rabbit.


We’re in. I’ve to find Trinity.