Reverse tethering of several Android devices via USB

Christian.D picture Christian.D · Mar 4, 2015 · Viewed 12.2k times · Source

I'm trying to setup a testing environment for my android app where the separate devices need an Internet connection, but don't have wireless capabilities.

So I decided on using usb reverse tethering. My host machine is running Ubuntu. I already managed to setup reverse tethering for one device, the connection is working and I can ping google.com from this device's adb shell.

When I connect a second device, the first tethering stops working. Both devices have the same IP adress configured on their internal usb0 interface.

Here's what I have so far:

  1. Port forwarding on host is activated

    echo 1 > /proc/sys/net/ipv4/ip_forward
    
  2. Iptables rule on host to route traffic:

    iptables -t nat -A POSTROUTING -s 169.254.255.2/24 -j MASQUERADE
    
  3. Plugin first device:

    ifconfig shows the device on usb0 @ ip 169.254.255.2/30
    
  4. On first device (with adb shell)

    > route add default gw 169.254.255.2 dev usb0
    > setprop net.dns1 8.8.8.8
    > ping google.com --> is giving results
    
  5. Plugin second device

    ifconfig shows this device on usb1 @ ip 169.254.255.2/30 
    
  6. On second device

    Add gw, set DNS like above
    

Now the second device can ping google.com, but the first one not.

When I change the internal IP or the IPs assigned to the hosts usb0, usb1 interfaces I am not able to connect to the devices via adb anymore.

I suspect this to be a networking problem, rather than a problem with ADB? Any Ideas?

Answer

Christian.D picture Christian.D · Mar 5, 2015

After a lot of googling and trial and error I finally found the solution for my particular setup.

What I did in the end, and what I missed in my first attempts, was to put each connected usb device into a separate subnet (see this answer on serverfault).

To put it clearly, the setup is now like following:

  1. iptables contains the following rule

    iptables -t nat -A POSTROUTING -j MASQUERADE
    
  2. the host's usb0 and usb1 interface, now in separate subnets

    usb0: inet addr:169.254.0.1  Bcast:169.254.15.255  Mask:255.255.240.0
    usb1: inet addr:169.254.16.1  Bcast:169.254.31.255  Mask:255.255.240.0
    
  3. internal usb0 iface of Android device connected on host's usb0:

    - usb0 169.254.0.2/20
    - default gw 169.254.0.1 (so the host's usb0 iface)
    
  4. internal usb0 iface of Android device connected on host's usb1:

    - usb0 169.254.16.2/20
    - default gw 169.254.16.1 (so the host's usb1 iface)
    

That way I now have Internet access (after adb shell setprop net.dns1 8.8.8.8) from each android device connected to the usb interfaces on my host.