Smartphone USB tethering

USB tethering is used to connect your OpenWrt Router to the Internet by using the your smartphone. It's more convenient and has better performance (lower latency) than turning your smartphone into an access point and using that. It also is less of a CPU load on your phone, charges your phone, and allows you the flexibility of doing things with your OpenWrt router that you cannot do with your phone like connecting multiple devices with ease, both wireless and wired, to each other and to the internet. In order to maximize performance, you should turn your tethered phone Wi-Fi and Bluetooth off.

  • :!: USB tethering is known to be problematic on iOS 14 devices. works without patch on latest trunk 01/2022, 21.02.1 needs patch
  • :!: Connecting your whole network to the Internet using the Smartphone might consume your monthly traffic quota very fast.
  • Follow USB reverse tethering to share the internet from router to the smartphone over USB.

For the easiest installation, have a wired upstream internet connection to boot-strap this process. You will need: the router, your tethering phone, necessary cables, a laptop and an upstream internet connection via Ethernet for initial setup. Instead of a wired upstream connection to plug into the router WAN port, is also possible to download necessary packages below, through your laptop while tethered to your phone, the same way you can get the OpenWrt distribution for your router.

A common protocol for Android based devices for tethering via USB is RNDIS:

opkg update
opkg install kmod-usb-net-rndis

However Android devices come with great diversity, therefor some require different protocols. For instance newer devices may use NCM, others may require EEM or even need a subset implementation.

NOTE: Try the following protocol(s) if you don't have a `usb0` interface come up or device keeps disconnecting:

opkg install kmod-usb-net-cdc-ncm

# Huawei may need its own implementation!
opkg install kmod-usb-net-huawei-cdc-ncm

# More protocols:
kmod-usb-net-cdc-eem
kmod-usb-net-cdc-ether
kmod-usb-net-cdc-subset

Extra steps depending on USB type and drivers for your router:

opkg update
opkg install kmod-nls-base kmod-usb-core kmod-usb-net kmod-usb-net-cdc-ether kmod-usb2

Additional steps for iOS devices:

opkg update
opkg install kmod-usb-net-ipheth usbmuxd libimobiledevice usbutils
 
# Call usbmuxd
usbmuxd -v
 
# Add usbmuxd to autostart
sed -i -e "\$i usbmuxd" /etc/rc.local

If you need to manually download the packages on another device for bootstrapping, see get_additional_software_packages. The Kernel modules will be in the URL of form downloads.openwrt.org/releases/[your release]/targets/[your target]/generic/packages/ and other packages (iOS stuff in this case) in downloads.openwrt.org/releases/[release]/packages/[instruction set]/packages/.

Connect the smartphone to the USB port of the router with the USB cable, and then enable USB Tethering from the Android settings. Turn on the phone's Developer Options [Find the Build information in the About Phone menu, and tap rapidly 7 x]. There is a Default USB Configuration: USB Tethering option. The phone will now immediately turn on USB Tethering mode when plugged into a configured router [or laptop], without further commands. However, it is necessary to remove the screen lock on the phone. A locked phone will not start USB Tethering by itself.

For iPhones, you may have to disable and re-enable the Personal Hotspot/Allow Others to Join setting on the iPhone to force the OpenWrt DHCP client to get an IP address from the eth1 iPhone interface. Disabling and re-enabling the Personal Hotspot/Allow Others to Join setting on the iPhone is also required if you disconnect the iPhone from the OpenWrt USB port and re-connect it later, unless you cache Trust records (see watchdog section and/or LeJeko's Github repository in reference section).

iPhones starting from iOS 11 will terminate the USB data connections after one hour by default to improve security. This can easily be changed via:

Settings > Touch ID/Face ID & Passcode > USB Accessories > ON (macworld)

On the router, enter:

# Enable tethering
uci set network.wan.ifname="usb0"
uci set network.wan6.ifname="usb0"
uci commit network
/etc/init.d/network restart

For iPhones, replace the interface name usb* with eth* depending on router.

It should be all working at this point. To activate wireless connections to the router, go to Network, Wireless and set then enable the interfaces.

Go to Network, Interfaces. You can either assign the existing WAN to usb0 like 3.a above, or create a whole new interface if you want to swap between the WAN Ethernet port and your tethering device (such as in a dual-wan fail-over situation). To make changes in the web interface equivalent to the above command line instructions: simply edit the existing default WAN interface, and change the physical device to usb0, then Save & Apply.

Instead, to create a whole new interface, make a new one called TetheringWAN, and bind to it the new *usb0* network device (restart if you do not see it yet. And, for some cases, the new interface may be called '*eth1*: check what the log is showing in your case). Set the protocol to DHCP client mode or DHCPv6 client mode if the ISP assigns IPv6, and under the Firewall Settings tab, place it into the WAN zone. Save changes.

See the following screenshots.

First page of the Create Interface wizard.

Firewall tab of the Create Interface Wizard. Very important to set it as WAN.

And the end result in the Interfaces page.

Whether you use command line (SSH), web interface (LUCI), and create a second interface or simply switch the existing WAN to usb0, the WAN activity light will go out. To reactive it's function (blinking on activity), go to System, LED Configuration, Name - Wan, Edit, and change Device: 'wan' to 'usb0'. Save & Save-&-Apply.

After committing the changes the new TetheringWAN should be activated. Otherwise, restart it with the buttons you find in the Interface page of LuCI web interface.

If all went well, you should be able to see something like the following in the kernel log

  • click on Status and then on Kernel Log to see this log from the LuCi web interface
  • or write “dmesg” in the console over SSH.
[  168.599245] usb 1-1: new high-speed USB device number 2 using orion-ehci
[  175.997290] usb 1-1: USB disconnect, device number 2
[  176.449246] usb 1-1: new high-speed USB device number 3 using orion-ehci
[  176.654650] rndis_host 1-1:1.0 usb0: register 'rndis_host' at usb-f1050000.ehci-1, RNDIS device, ee:da:c0:50:ff:44

Note how the last line tells us that this new “RNDIS device” was bound to interface usb0.

:!: The above messages will not be shown with iPhone tethering.

If your tethering connection fails every so often, and:

  • You see in your client devices that there is no internet connectivity, and
  • Your phone is still showing a good 4G/tower connection, and tethering enabled, and
  • Simply unplugging your tethering phone and plugging it back into the router fixes the problem

Then it might be fixed with the following solution:

# Install packages
opkg update
opkg install hub-ctrl
 
# Save connectivity checking script
cat << "EOF" > /root/wan-watchdog.sh
#!/bin/sh
 
# Fetch WAN gateway
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
network_get_gateway NET_GW "${NET_IF}"
 
# Check WAN connectivity
TRIES="0"
while [ "${TRIES}" -lt 5 ]
do
    if ping -c 1 -w 3 "${NET_GW}" &> /dev/null
    then exit 0
    else let TRIES++
    fi
done
 
# Restart network
/etc/init.d/network stop
hub-ctrl -h 0 -P 1 -p 0
sleep 1
hub-ctrl -h 0 -P 1 -p 1
/etc/init.d/network start
EOF
chmod +x /root/wan-watchdog.sh
 
# Add cron job
cat << "EOF" >> /etc/crontabs/root
* * * * * /root/wan-watchdog.sh
EOF

Every 1 minute, the script will be run, ping WAN gateway, and if there are 5 consecutive failures, it will stop the network, power off the USB hub (which will terminate tethering on the phone), power it back on, then restart the network. This solution is much faster than restarting the whole router.

Once you set up iPhone tethering as per above, you'll notice several issues:

  • usbmuxd needs to be started manually after every reboot
  • On iPhone, you need to set up trust again after every router reboot
  • If your cellular signal is weak, tethering will disconnect every now and then and you'll need to unplug and reconnect USB cable

Save following script to some location that survives reboot, e.g. /etc/lockdown, and execute it after every reboot. It should keep tethering up and running as long as iPhone is connected.

# Save watchdog script
mkdir -p /etc/lockdown
cat << "EOF" > /etc/lockdown/watchdog.sh
#!/bin/sh
# A small script to make life with iPhone tethering less cumbersome on OpenWrt
# Petr Vyskocil, Apr 2020
# Public domain
 
# After you successfully allow iPhone tethering, copy files with name like
# /var/lib/lockdown/12345678-9ABCDEF012345678.plist to /etc/lockdown/locks.
# That way, you won't have to set up trust again after router reboots.
if [ -e /etc/lockdown/locks ]
then
    mkdir -p /var/lib/lockdown
    cp -f /etc/lockdown/locks/* /var/lib/lockdown/
fi
 
# lockdown records restored, now we can launch usbmuxd. Don't launch it sooner!
usbmuxd
 
# We are up and running now. But unfortunately if your carrier signal is weak, iPhone will
# drop connection from time to time and you'd have to unplug and replug USB cable to start tethering
# again. Script below automates that activity.
 
# First wait a bit - we just brought the interface up by usbmuxd
sleep 20
 
# If we see iPhone ethernet interface, try to ping iPhone router's address (172.20.10.1).
# When the ping is unsuccessful, rebind iPhone ethernet USB driver and wait for things to settle down
while :
do
    for i in /sys/bus/usb/drivers/ipheth/*:*
    do
        test -e "${i}" || continue
        ping -w 3 172.20.10.1 &> /dev/null
        if [ "${?}" -ne 0 ]; then
            echo "${i##*/}" > "${i%/*}"/unbind
            echo "${i##*/}" > "${i%/*}"/bind
            sleep 20
        fi
    done
    sleep 1
done
EOF
chmod +x /etc/lockdown/watchdog.sh
 
# Add watchdog script to autostart
sed -i -e "\$i (/etc/lockdown/watchdog.sh) &" /etc/rc.local

If your Android phone does not seem to detect that there is something attached to the USB port and refuses to switch to USB tethering, you might want to install DriveDroid and try to enable various methods of using USB guest for its own functionality. This does solve that issue in my phone (which is running LineageOS nightly and sometimes after I update does show this issue). You will probably need root (administrator) access on your device though.

Cell phone companies are slowing transitioning to IPv6, and they might assign your SIM an IPv6 subnet bigger than a /64, typically, a /56 or /48, but sometimes a /60. You may use an assignment larger than a /64 (/56 or /48) to provide native IPv6 addresses and connectivity to your LAN. A quick way to test, assuming your device is *usb0*, is to create the TetheringWAN interface as suggested above, but instead of DHCP client, choose DHCPv6 client instead.

If your provider does not assign a subnet larger than a /64, you could use NAT6 and IPv6 masquerading to enable IPv6 access for your LAN clients but you should really ask your provider to assign you a /56 instead. One of the features of IPv6 is enough address space to move away from NAT and CGNAT.
You may create another interface on *usb0* over the usual IPv4 DHCP client and thus have two WAN interfaces over *usb0*, with the caveat that the IPv4 wan interface would be doing NAT and tunneling your traffic, which is overhead native IPv6 would avoid.
Install the mwan3 and luci-app-mwan3 packages to manage traffic over both (or up to 250 WAN) interfaces with kernel policy routing, this is especially useful if you're using your cell phone as a secondary WAN interface.

If you don't see something like the sample kernel log output in your device's log then your device might be lacking proper USB drivers (drivers to operate the USB controllers at all). Check Installing USB drivers and report the issue in a bug report or in the mailing list, as devices should have base USB drivers integrated and working already.

For other issues it might be worth it to check the article about using RNDIS dongles as Android tethering is using the same protocol.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2024/03/07 18:20
  • by s2s2