DHCP + guest network + android =?

I have a MiFi that is broadcasting two SSIDs, one encrypted one guest. The encrypted SSID is bound to the LAN interface and issues DHCP on 10.1.1.0/25, while the guest SSID is bound to LAN2 interface issues DHCP on 10.1.1.128/25.

By default, an OpenVPN connection is made and tun0 serves as the default gateway. All of this works just fine on an array of devices - Windows PC, iOS, and Android. When they join the encrypted SSID, they get issued a DHCP address on the lower range. When they join the guest SSID, they get issued a DHCP address on the higher range. Regardless, all traffic is going out via tun0.

The last step is to add a route in /etc/rc.local to send the traffic from the guest subnet directly out wwan0 instead of through the VPN tunnel (tun0).

ip rule add from 10.1.1.128/25 table streamer
ip route add default via $WAN_GW table streamer

This setup works well on nearly every device except some Android devices (and not all). Win 10 laptop, iPhone, and some Android devices all can connect via DHCP to either SSID and get routed appropriately. However, when connecting to the guest SSID, some Android devices get stuck at “Obtaining IP address…” and loop through multiple attempts until finally arriving at a DHCP error.

What’s odd is, it seems to be the route for the guest network that causes the problem. When I remove the route, the troublesome Android devices connect just fine to the guest SSID, but of course everything on that SSID is still routing through tun0 instead of going out directly on wwan0. If I then re-add the route after the device has accepted its DHCP lease, all of its traffic is routed correctly.

Also interesting, is it’s only a problem with DHCP addressing. If I configure the Android devices to connect with a static IP and the route has already been added, they connect to the guest network just fine and are routed correctly.

Any idea what it could be about some of these Android phones and tablets that is not allowing DHCP addressing when my guest route is enabled??

/etc/config/network

config interface ‘loopback’
option ifname ‘lo’
option proto ‘static’
option ipaddr ‘127.0.0.1’
option netmask ‘255.0.0.0’

config globals ‘globals’
option ula_prefix ‘fd5f:33fb:2b65::/48’

config interface ‘lan’
option type ‘bridge’
option ifname ‘eth1’
option proto ‘static’
option ip6assign ‘60’
option hostname ‘GL-MIFI-7d0’
option ipaddr ‘10.1.1.1’
option netmask ‘255.255.255.128’

config interface ‘lan2’
option ifname ‘wlan2’
option proto ‘static’
option ip6assign ‘60’
option hostname ‘GL-MIFI-7d0’
option ipaddr ‘10.1.1.129’
option netmask ‘255.255.255.128’

config interface ‘wan’
option ifname ‘eth0’
option proto ‘dhcp’
option hostname ‘GL-MIFI-7d0’
option metric ‘10’
option peerdns ‘0’
option custom_dns ‘1’
option dns ‘8.8.8.8 8.8.4.4’

config interface ‘wan6’
option ifname ‘eth0’
option proto ‘dhcpv6’

config interface ‘tethering’
option proto ‘dhcp’
option metric ‘30’
option ifname ‘eth2’
option peerdns ‘0’
option dns ‘8.8.8.8 8.8.4.4’

config interface ‘DROIDTETHER’
option proto ‘dhcp’
option ifname ‘usb0’
option metric ‘30’
option peerdns ‘0’
option dns ‘8.8.8.8 8.8.4.4’

config interface ‘modem’
option ifname ‘wwan0’
option service ‘fdd-lte’
option apn ‘fast.t-mobile.com
option proto ‘qmi’
option device ‘/dev/cdc-wdm0’
option metric ‘40’
option disabled ‘0’
option peerdns ‘0’
option dns ‘8.8.8.8 8.8.4.4’

config interface ‘VPN_client’
option ifname ‘tun0’
option proto ‘none’

/etc/config/wireless

config wifi-device ‘radio0’
option type ‘mac80211’
option path ‘platform/ar933x_wmac’
option noscan ‘1’
option country ‘US’
option channel ‘11’
option txpower ‘10’
option hwmode ‘11g’

config wifi-iface ‘default_radio0’
option device ‘radio0’
option network ‘lan’
option mode ‘ap’
option encryption ‘psk-mixed’
option wds ‘0’
option ifname ‘wlan0’
option ssid ‘encrypted’
option key ‘pass1’
option wmm ‘0’

config wifi-iface
option device ‘radio0’
option mode ‘ap’
option wds ‘0’
option ifname ‘wlan2’
option ssid ‘guest’
option key ‘pass2’
option wmm ‘0’
option encryption ‘none’
option network ‘lan2’

/etc/config/dhcp

config dnsmasq
option boguspriv ‘1’
option localise_queries ‘1’
option expandhosts ‘1’
option leasefile ‘/tmp/dhcp.leases’
option rebind_protection ‘0’
option local ‘/RVITclient.lan/’
option domain ‘RVITclient.lan’
option localservice ‘0’
option nonwildcard ‘0’
list server ‘8.8.8.8’
list server ‘8.8.4.4’
option noresolv ‘1’
option readethers ‘1’
option authoritative ‘1’

config dhcp ‘lan’
option interface ‘lan’
option leasetime ‘12h’
option limit ‘50’
option start ‘1’

config dhcp ‘wan’
option interface ‘wan’
option ignore ‘1’

config odhcpd ‘odhcpd’
option maindhcp ‘0’
option leasefile ‘/tmp/hosts/odhcpd’
option leasetrigger ‘/usr/sbin/odhcpd-update’

config domain ‘localhost’
option name ‘console.gl-inet.com
option ip ‘10.1.1.1’

config dhcp ‘lan2’
option leasetime ‘12h’
option interface ‘lan2’
option limit ‘50’
option start ‘1’

Did you add the guest interface to lan zone on firewall?

Yes, both the interfaces are in the LAN zone.

I was able to find a solution to this problem after much experimentation, so figured I would post it back in case anyone else encounters the same thing.

It looks as though some devices (Android and iOS, perhaps others too) would not complete a DHCP lease acquisition with dnsmasq if the IP offered was subject to an iptables rule to use a different default route. I’m still not precisely sure why this is, but perhaps the device tests its default route with the offered IP, sees its going to be given a default route different than the one in the main routing table and rejects the DHCP lease.

Instead, if I write the iptables rule to apply to a specific interface (vlan2) rather a range of IPs being offered on that interface, all devices will accept the lease and complete the transaction with dnsmasq. Perhaps in these instances, the device looks for a rule based on the offered IP, doesn’t see it will be diverted from the default route in the main routing table, and accepts the lease. Once joined, it routes correctly through the alternate default gateway specified for vlan2.

So instead of

ip rule add from 10.1.1.128/25 table streamer
ip route add default via $WAN_GW table streamer

This seems to work with all devices (also specified priority ahead of main table rule)

ip rule add iif br-vlan2 lookup streamer priority 999
ip route add default via $WAN_GW table streamer