postmarketos-base-ui: enable USB tethering v2
USB tethering support
Enable USB tethering on postmarketOS' setup with unudhpcd and NetworkManager. Users can share their WWAN or WiFi iface of their phones with desktops/laptops over USB while still accessing the phone over USB with SSH.
What is USB tethering?
Several Android/iOS phones allow you to share your WiFi or WWAN interface to a connected laptop/desktop over USB. This is similar to a WiFi hotspot, but over USB. As an user, you benefit from lower power consumption, no need to secure your hotspot, and you can share your WiFi connection as well. Bonus: US carriers cannot see that we're tethering and charge for this feature like on Android/iOS as we don't report this to the carrier like Android/iOS OS does :)
How does it work?
NetworkManager supports tethering out-of-the-box under the IPv4/IPv6 method shared
which spawns dnsmasq for DHCP requests from the connected client and DNS forwarding from the client to the DNS server configured on the phone. However, this heavily conflicts with postmarketOS setup in its initfs as unudhcpd also acts as DHCP server. Moreover, by default, NetworkManager does not manage USB Ethernet gadgets like we create in initfs.
This MR solves these problems as followed:
- Expand NetworkManager with a
reapply
dispatcher action so we can add on the iface changes that are applied when a NetworkManager connection profile is changed. After a change to the connection profile, a reapply job needs to be executed which triggers the dispatcher action. - Execute a dispatcher script when the connection profile is reapplied:
-
manual
mode which is like in initfs, IP is static set to 172.16.42.1 for the phone, 172.16.42.2 for the connected client, iface becomes managed by NetworkManager and unudhcpd handles DHCP requests. If unudhcpd is not running, it gets spawned. -
shared
mode which is USB tethering, NetworkManager spawns dnsmasq and uses IP is 172.16.42.1 for the phone and a DHCP server for the connected client. The whole available range is used. If unudhcpd is running, it gets killed to avoid conflicts with dnsmasq. NetworkManager will also arrange the necessary configs so IP forwarding is enabled in the kernel and firewall. These configs are removed when tethering is disabled again.
When the mode is changed, UDC of the gadget is reactivated to trigger a disconnect/connect event on the connected client. This way, we ensure that the client performs a DHCP request to request an IP from either unudhcpd or dnsmasq, depending on the mode. The script logs with logger
to syslog under the tag nm-tethering
.
No matter which mode is active, SSH login over USB still works as the phone still uses the same IP 172.16.42.1.
How to test this?
Checkout the branch and build it with pmbootstrap. mrtest
does not work as the CI times out, CI builds skipped.
To use this feature:
- Connect your phone over USB to your desktop.
- On the phone, open Settings
- Go to the Network panel tab.
- You should see 1 wired connection at the top, tab the edit settings button (gear)
- An old panel opens which doesn't fit your screen (use Phosh Mobile Settings to enable scale-to-fit for this panel only, it will be shown in the list of active apps).
- Go to the IPv4 tab.
- Select 'Shared to other computers' and tab the Apply button in the right corner.
NM should now launch its own dnsmasq instance, configure the firewall to allow internet sharing over usb0. It will trigger a script to re-establish the USB ethernet connection with the desktop. This way, the desktop will get an IP in the 10.X.X.X range and also a DNS server to which it can send DNS queries for this connection. Normally, you should be able to access the Web over usb0 now if you have WiFi or WWAN turned ON on the phone.
TODOs
-
Once unplugged, it does not autoconnect anymore when plugged in again. NetworkManager blocks everything until the user manually enables the USB Ethernet device in GNOME Settings. This is resolved by setting the connection autoconnect
property totrue
. -
On each boot, NetworkManager creates a new connection profile for usb0
. -
GNOME Settings does not seem to perform a reapply of the connection on the iface when pressing 'Apply' in the connection setting UI. -
dnsane support (!3805 (closed))?
Draft until these TODOs are addressed or a solution if on the way for them.
Upstream
-
NetworkManager MR 1311 -
NetworkManager dnsmasq fix MR 43470 -
GNOME Settings reapply on device fix MR 1642 -
NetworkManager upgrade to 1.42.0 MR 44105 -
GNOME Settings reapply patch backported to Alpine MR 44146 -
dnsmasq missing pre-install script MR 44152
Issues & merge requests
Fixes #1904 (moved)
Fixes unudhcpd#1 (moved)
Contributes to #1518
Superseeds !3301 (closed)
Tested on Plasma Mobile, but Settings cannot set the connection to shared mode and back. So only the CLI way is available there.
CC: @craftyguy