Hi Jan,
Outside of my current RF environment Android hotspot is generally pretty good and I use this quite often, when on-the-go. Performance is poor when I'm on location at the airbnb where 2.4/5GHz wifi is congested. If I had my spec-an on-site I could show you ;)
Client isolation on the android is a bummer and I've got wired-only machines that need egress. OpenBSD provides some nice options in this usecase...
Byron
On Sun, Mar 22, 2026, at 14:13, Jan Stary wrote:
> How does this setup compare to simply having the android act
> as a mobile hotspot? Meaning the connection itself: stability,
> throughput, lag; obviously there is less configuration.
>
> Jan
>
>
>
> On Mar 22 12:53:01, byronklippert@ml1.net wrote:
>> Hi Bartek,
>>
>> I'm also using an Android phone for USB tethering over 5G. 90% of the time it works 100% of the time ;) After the iniital setup and troubleshooting I came up with the router configuration detailed below.
>>
>> Background
>> Temporary setup at an airbnb with poor wifi (heavy interference, variable throughput). 5G provides better peak performance but still fluctuates with load. Router wifi client is limited to 2.4 GHz due to older hardware.
>>
>> I setup hotplugd attach to remove ral from egress, remov autoconf and pull the ral default route from the table. I leave ral up and associated with the AP (when on 5G) that way when I transiton back to ral I just need to add it to the egress group, add autoconf flag and re-insert the default route.
>>
>> I've also dropped unbound and now use public DNS. resolvd is disabled, and there's no dhcpd on the LAN—everything is statically configured, for now.
>>
>> Objective
>> OpenBSD i386/7.8 ALIX router that prefers wifi but automatically switches to urndis when USB is connected, with minimal packet loss, and falls back to wifi on disconnect. Router with ral (wifi) and vr (LAN). pf for NAT/filtering. hotplugd detects urndis and triggers reconfiguration of interfaces and routes.
>>
>> Outstanding Issues
>> For some reason my setup doesn't always switch cleanly to the urndis interface on initial connect. Not sure if the issue is the phone, urndis, or my setup. For example; the first time I connect USB initial connect/disconnect seems to get stuck transitioning to 5G but subsequent cycles are flawless. If I leave it on wifi for a day and come back to connect USB I have to plug/unplug to get it to transition cleanly.
>>
>> The other issue is sometimes the 5G connection gets to congested and packets stop flowing throught the phone and I have to connect/disconnect again. Might have to setup ifstated to check for this condition and reinitialize the interface.
>>
>> Open to suggestions on making this setup more robust or possibly even setting it up for active/active, dependent on which WAN has better throughput in the moment.
>>
>>
>> router:/home/admin $ cat /etc/hostname.vr0
>> inet 172.16.100.1 255.255.255.0
>> up
>> ### EOF
>>
>> router:/home/admin $ cat /etc/hostname.ral0
>> nwid "..." wpakey ...
>> inet autoconf
>> up
>> ### EOF
>>
>> router:/home/admin $ doas cat /etc/pf.conf:
>> # Marcros
>> lan_if = "vr0"
>> wlan_if = "ral0"
>>
>> # Options
>> set block-policy drop
>> set skip on lo0
>>
>> # Match rules
>> match in all scrub (no-df random-id max-mss 1440)
>> match out on egress to any nat-to (egress)
>>
>> # Block rules
>> antispoof quick for egress
>> block all
>>
>> # Filtering rules
>> pass quick on egress inet proto { tcp, udp } to any port { bootps, bootpc }
>> pass in quick on $lan_if inet proto tcp from $lan_if:network to ($lan_if) port ssh
>> pass on $lan_if from $lan_if:network to any label "clear"
>> pass out on egress to any label "clear"
>> ### EOF
>>
>> router:/home/admin $ doas cat /etc/hotplug/attach
>> #!/bin/sh
>>
>> DEVCLASS=$1
>> DEVNAME=$2
>>
>> case $DEVCLASS in
>> 3)
>> case $DEVNAME in
>> urndis0)
>> logger "hotplugd: USB tethering device urndis0 attached"
>>
>> logger "hotplugd: bringing up urndis0 interface"
>> ifconfig $DEVNAME autoconf && sleep 3
>>
>> logger "hotplugd: deleting default route via ral0"
>> ral0defaultroute=$(grep "next-server" /var/db/dhcpleased/ral0 | awk '{print $2}')
>> route delete default $ral0defaultroute -ifp ral0
>> ifconfig ral0 -autoconf -group egress
>>
>> logger "hotplugd: flushing states"
>> pfctl -k label -k clear
>>
>> logger "hotplugd: end of attach script"
>> ;;
>> esac
>> esac
>> ### EOF
>>
>> router:/home/admin $ doas cat /etc/hotplug/detach
>> #!/bin/sh
>>
>> DEVCLASS=$1
>> DEVNAME=$2
>>
>> case $DEVCLASS in
>> 3)
>> case $DEVNAME in
>> urndis0)
>> logger "hotplugd: USB tethering device urndis0 detached"
>>
>> logger "hotplugd: checking to see if ral0 is active"
>> ifconfig ral0 | grep -q "status: active"
>> ral0_status=$?
>>
>> if [[ $ral0_status -eq 0 ]]; then
>> logger "hotplugd: ral0 is active, adding default route"
>> ral0defaultroute=$(grep "next-server" /var/db/dhcpleased/ral0 | awk '{print $2}')
>> route add default $ral0defaultroute -ifp ral0
>> ifconfig ral0 autoconf group egress
>>
>> logger "hotplugd: flushing states"
>> pfctl -k label -k clear
>>
>> elif [[ $ral0_status -eq 1 ]]; then
>> logger "hotplugd: ral0 is not active, running netstart script"
>> sh /etc/netstart ral0
>>
>> else
>> logger "hotplugd: can't determine status of ral0"
>> fi
>>
>> logger "hotplugd: end of detach script"
>> ;;
>> esac
>> esac
>> ###EOF
>>
>>
>> ### Router state on ral wireless...
>>
>> router:/home/admin $ doas dhcpleased -v -d
>> state_transition[ral0] Down -> Rebooting, timo: 1
>> DHCPREQUEST on ral0
>> DHCPACK on ral0 from 22:6a:94:99:52:41/192.168.0.1 to 00:14:85:d3:f2:8e/192.168.0.132
>> adding 192.168.0.132 to ral0 (lease from 192.168.0.1)
>> adding nameservers 192.168.0.1 (lease from 192.168.0.1 on ral0)
>> state_transition[ral0] Rebooting -> Bound, timo: 43200
>> configure_interface ral0
>>
>>
>> router:/home/admin $ doas ifconfig egress
>> ral0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
>> lladdr 00:14:85:d3:f2:8e
>> index 4 priority 4 llprio 3
>> groups: wlan egress
>> media: IEEE802.11 autoselect (OFDM36 mode 11g)
>> status: active
>> ieee80211: nwid "..." chan 1 bssid 20:6a:94:99:52:48 -109dBm wpakey wpaprotos wpa2 wpaakms psk wpaciphers ccmp wpagroupcipher ccmp
>> inet 192.168.0.132 netmask 0xffffff00 broadcast 192.168.0.255
>>
>>
>> router:/home/admin $ doas route -n show -inet
>> Routing tables
>>
>> Internet:
>> Destination Gateway Flags Refs Use Mtu Prio Iface
>> default 192.168.0.1 UGS 1 126 - 12 ral0
>> 127.0.0.1 127.0.0.1 UHl 0 457 32768 1 lo0
>> 172.16.100/24 172.16.100.1 UCn 1 346 - 4 vr0
>> 172.16.100.1 00:0d:b9:0d:a8:1c UHLl 0 18306 - 1 vr0
>> 172.16.100.2 20:7b:d2:33:53:e7 UHLc 1 1934340 - L 3 vr0
>> 172.16.100.255 172.16.100.1 UHb 0 78640 - 1 vr0
>> 192.168.0/24 192.168.0.132 UCn 1 0 - 8 ral0
>> 192.168.0.1 22:6a:94:99:52:41 UHLch 1 4 - 7 ral0
>> 192.168.0.132 00:14:85:d3:f2:8e UHLl 0 3 - 1 ral0
>> 192.168.0.255 192.168.0.132 UHb 0 0 - 1 ral0
>>
>>
>> ### Router state after connecting Android phone...
>>
>> router:/home/admin $ doas dhcpleased -v -d (cont'd)
>> state_transition[urndis0] Down -> Rebooting, timo: 1
>> DHCPREQUEST on urndis0
>> DHCPACK on urndis0 from fe:1a:ce:27:08:df/10.41.194.246 to 9a:c7:ab:49:28:aa/10.41.194.214
>> adding 10.41.194.214 to urndis0 (lease from 10.41.194.246)
>> adding nameservers 10.41.194.246 (lease from 10.41.194.246 on urndis0)
>> state_transition[urndis0] Rebooting -> Bound, timo: 1800
>> configure_interface urndis0
>> Removed autoconf flag from ral0
>> deleting nameservers 192.168.0.1 (lease from 192.168.0.1 on ral0)
>> deleting 192.168.0.132 from ral0 (lease from 192.168.0.1)
>> deconfigure_interface ral0
>>
>>
>> router:/home/admin $ doas ifconfig egress
>> urndis0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
>> lladdr 9a:c7:ab:49:28:aa
>> index 89 priority 0 llprio 3
>> groups: egress
>> inet 10.41.194.214 netmask 0xffffff00 broadcast 10.41.194.255
>>
>>
>> router:/home/admin $ doas ifconfig ral0
>> ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
>> lladdr 00:14:85:d3:f2:8e
>> index 4 priority 4 llprio 3
>> groups: wlan
>> media: IEEE802.11 autoselect (OFDM36 mode 11g)
>> status: active
>> ieee80211: nwid "..." chan 1 bssid 20:6a:94:99:52:48 -107dBm wpakey wpaprotos wpa2 wpaakms psk wpaciphers ccmp wpagroupcipher ccmp
>>
>>
>> router:/home/admin $ doas route -n show -inet
>> Routing tables
>>
>> Internet:
>> Destination Gateway Flags Refs Use Mtu Prio Iface
>> default 10.41.194.246 UGS 1 936 - 8 urndis0
>> 10.41.194/24 10.41.194.214 UCn 1 0 - 4 urndis0
>> 10.41.194.214 9a:c7:ab:49:28:aa UHLl 0 11 - 1 urndis0
>> 10.41.194.246 fe:1a:ce:27:08:df UHLch 1 12 - 3 urndis0
>> 10.41.194.255 10.41.194.214 UHb 0 0 - 1 urndis0
>> 127.0.0.1 127.0.0.1 UHl 0 457 32768 1 lo0
>> 172.16.100/24 172.16.100.1 UCn 1 346 - 4 vr0
>> 172.16.100.1 00:0d:b9:0d:a8:1c UHLl 0 18307 - 1 vr0
>> 172.16.100.2 20:7b:d2:33:53:e7 UHLc 1 1935000 - L 3 vr0
>> 172.16.100.255 172.16.100.1 UHb 0 78640 - 1 vr0
>>
>>
>> ### LAN client traceroute before transition to 5G...
>> c:\>tracert 1.1.1.1
>>
>> Tracing route to one.one.one.one [1.1.1.1]
>> over a maximum of 30 hops:
>>
>> 1 <1 ms <1 ms <1 ms yeg-router [172.16.100.1]
>> 2 3 ms 5 ms 3 ms 192.168.0.1
>> 3 17 ms 18 ms 16 ms 68.148.160.1
>> 4 16 ms 15 ms 18 ms rc2ar-be131-1.ed.shawcable.net [64.59.184.137]
>> ...
>> 15 31 ms 32 ms 29 ms one.one.one.one [1.1.1.1]
>>
>> Trace complete.
>>
>>
>> ### LAN client ping response during transition to 5G...
>> c:\>ping -t 1.1.1.1
>>
>> Pinging 1.1.1.1 with 32 bytes of data:
>> Reply from 1.1.1.1: bytes=32 time=29ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=30ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=33ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=38ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=32ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=35ms TTL=58 <--- connect USB
>> Request timed out.
>> Reply from 1.1.1.1: bytes=32 time=58ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=61ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=56ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=43ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=44ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=66ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=61ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=48ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=69ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=53ms TTL=47
>>
>> Ping statistics for 1.1.1.1:
>> Packets: Sent = 17, Received = 16, Lost = 1 (5% loss),
>> Approximate round trip times in milli-seconds:
>> Minimum = 29ms, Maximum = 69ms, Average = 47ms
>> Control-C
>> ^C
>>
>>
>> ### Router ping response during transition to 5G...
>> router:/home/admin $ ping 1.1.1.1
>> PING 1.1.1.1 (1.1.1.1): 56 data bytes
>> 64 bytes from 1.1.1.1: icmp_seq=0 ttl=59 time=31.484 ms
>> 64 bytes from 1.1.1.1: icmp_seq=1 ttl=59 time=32.699 ms
>> 64 bytes from 1.1.1.1: icmp_seq=2 ttl=59 time=32.148 ms
>> 64 bytes from 1.1.1.1: icmp_seq=3 ttl=59 time=30.861 ms
>> 64 bytes from 1.1.1.1: icmp_seq=4 ttl=59 time=34.582 ms <--- connect USB
>> 64 bytes from 1.1.1.1: icmp_seq=8 ttl=48 time=59.442 ms
>> 64 bytes from 1.1.1.1: icmp_seq=9 ttl=48 time=51.786 ms
>> 64 bytes from 1.1.1.1: icmp_seq=10 ttl=48 time=46.138 ms
>> 64 bytes from 1.1.1.1: icmp_seq=11 ttl=48 time=38.190 ms
>> 64 bytes from 1.1.1.1: icmp_seq=12 ttl=48 time=48.407 ms
>> 64 bytes from 1.1.1.1: icmp_seq=13 ttl=48 time=42.599 ms
>> ^C
>>
>>
>> ### LAN client traceroute after transition to 5G...
>> c:\>tracert 1.1.1.1
>>
>> Tracing route to one.one.one.one [1.1.1.1]
>> over a maximum of 30 hops:
>>
>> 1 <1 ms <1 ms <1 ms yeg-router [172.16.100.1]
>> 2 2 ms 2 ms 2 ms 10.41.194.246
>> 3 6 ms 3 ms 3 ms 192.0.0.1
>> 4 * * * Request timed out.
>> ...
>> 18 83 ms 42 ms 61 ms one.one.one.one [1.1.1.1]
>>
>> Trace complete.
>>
>>
>> ### LAN client ping behaviour during transition back to ral wireless...
>> c:\>ping -t 1.1.1.1
>>
>> Pinging 1.1.1.1 with 32 bytes of data:
>> Reply from 1.1.1.1: bytes=32 time=72ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=48ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=60ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=74ms TTL=47
>> Reply from 1.1.1.1: bytes=32 time=60ms TTL=47 <--- disconnect USB
>> Reply from 1.1.1.1: bytes=32 time=33ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=31ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=32ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=33ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=32ms TTL=58
>> Reply from 1.1.1.1: bytes=32 time=33ms TTL=58
>>
>> Ping statistics for 1.1.1.1:
>> Packets: Sent = 11, Received = 11, Lost = 0 (0% loss),
>> Approximate round trip times in milli-seconds:
>> Minimum = 31ms, Maximum = 74ms, Average = 46ms
>> Control-C
>> ^C
>>
>>
>> ### Router ping behaviour during transition back to ral wireless...
>> router:/home/admin $ ping 1.1.1.1
>> PING 1.1.1.1 (1.1.1.1): 56 data bytes
>> 64 bytes from 1.1.1.1: icmp_seq=0 ttl=48 time=47.390 ms
>> 64 bytes from 1.1.1.1: icmp_seq=1 ttl=48 time=72.350 ms
>> 64 bytes from 1.1.1.1: icmp_seq=2 ttl=48 time=61.727 ms
>> 64 bytes from 1.1.1.1: icmp_seq=3 ttl=48 time=52.997 ms
>> 64 bytes from 1.1.1.1: icmp_seq=4 ttl=48 time=69.023 ms <--- disconnect USB
>> ping: sendmsg: Can't assign requested address
>> ping: wrote 1.1.1.1 64 chars, ret=-1
>> 64 bytes from 1.1.1.1: icmp_seq=6 ttl=59 time=36.700 ms
>> 64 bytes from 1.1.1.1: icmp_seq=7 ttl=59 time=64.899 ms
>> 64 bytes from 1.1.1.1: icmp_seq=8 ttl=59 time=38.605 ms
>> 64 bytes from 1.1.1.1: icmp_seq=10 ttl=59 time=32.515 ms
>> ^C
>>
>>
>> ### LAN client traceroute after transition back to ral wireless...
>> c:\>tracert 1.1.1.1
>>
>> Tracing route to one.one.one.one [1.1.1.1]
>> over a maximum of 30 hops:
>>
>> 1 <1 ms <1 ms <1 ms yeg-router [172.16.100.1]
>> 2 7 ms 2 ms 3 ms 192.168.0.1
>> 3 16 ms 14 ms 16 ms 68.148.160.1
>> 4 37 ms 15 ms 15 ms rc2ar-be131-1.ed.shawcable.net [64.59.184.137]
>> ...
>> 15 29 ms 32 ms 35 ms one.one.one.one [1.1.1.1]
>>
>> Trace complete.
>>
>>
>> Cheers,
>> Byron
>>
>>
>> On Tue, Mar 17, 2026, at 16:07, Bartek Dygas wrote:
>> > On 3/17/26 12:21 AM, Zé Loff wrote:
>> >> Does your mobile ISP support tethering/connection sharing? I've had
>> >> issues with a provider that only allows for the phone itself to access
>> >> the internet, and blocks shared connections.
>> > Yes, USB Tethering with this phone works correctly on a different
>> > computer with ArchLinux.
>> >
>> > Attachments:
>> > * OpenPGP_0x5AEF30C3C0EAEC93.asc
>> > * OpenPGP_signature.asc
>>
>> On Tue, Mar 17, 2026, at 16:07, Bartek Dygas wrote:
>> > On 3/17/26 12:21 AM, Zé Loff wrote:
>> >> Does your mobile ISP support tethering/connection sharing? I've had
>> >> issues with a provider that only allows for the phone itself to access
>> >> the internet, and blocks shared connections.
>> > Yes, USB Tethering with this phone works correctly on a different
>> > computer with ArchLinux.
>> >
>> > Attachments:
>> > * OpenPGP_0x5AEF30C3C0EAEC93.asc
>> > * OpenPGP_signature.asc
>>
>> --
>> Byron Klippert
>> byronklippert@ml1.net
>>
>>
--
Byron Klippert
byronklippert@ml1.net
No comments:
Post a Comment