Skip to content

📡 Dual-Router & Access Point Architecture (Flint 2 & Archer C7) ​

Comprehensive documentation of the OpenWrt router/AP topology, VLAN bridging, DHCP/DNS integration, Wi-Fi roaming optimizations, issue history, and configuration guidelines to prevent operational regressions.


🏛️ Topology & Device Roles ​


⚙️ Device Specifications & Service Matrix ​

ParameterPrimary Router (Flint 2)Access Point (Archer C7 v5)
ModelGL.iNet GL-MT6000TP-Link Archer C7 v5
SoC / ChipsetsMediaTek MT7986 (Filogic 830) + MT7915Qualcomm Atheros QCA9563 (2.4G ath9k) + QCA9880 (5G ath10k)
Management IP192.168.0.1192.168.0.2 (Static on br-lan, Gateway 192.168.0.1)
Web GUI Ports80 / 443 (GL.iNet Nginx) | 8080 / 8443 (LuCI uhttpd)80 / 443 (OpenWrt LuCI uhttpd)
DHCP / DNS RoleAuthoritative Server (dnsmasq + odhcpd + AdGuard Home)Disabled (ignore '1', dynamicdhcp '0', proto 'none')
2.4 GHz SSID (Main)kevin (Channel 11 / HT20 / WPA2-PSK)kevin (Channel 6 / HT20 / WPA2-PSK)
5 GHz SSID (Main)kevin-but-better (Channel 36 / HE40 / WPA2-PSK)kevin-but-better (Channel 44 / VHT40 / WPA2-PSK)
2.4 GHz SSID (IoT)kevin-iot (VLAN 69 / WPA2-PSK)kevin-iot (VLAN 69 / WPA2-PSK)
802.11r (FT)Disabled (ieee80211r '0')Disabled (ieee80211r '0')
802.11k (RRM)Enabled (ieee80211k '1')Enabled (ieee80211k '1')
Bridge Ageing15 seconds (ageing_time '15')15 seconds (ageing_time '15')
Deauth Protectiondisassoc_low_ack '0'disassoc_low_ack '0'

🛠️ Issues Encountered & Permanent Fixes Implemented ​

1. next-openwrt-stats Dashboard Single-Character MAC & GL.iNet Tag Bug ​

  • Symptom: OpenWrt dashboard showed corrupted 1-character MACs (B, 7, etc.) with Infinite leases, and client names were missing. Interface bandwidth graphs failed with Failed to parse ubus response.
  • Root Causes:
    1. Upstream code bug: device.mac[0] in JavaScript on a string MAC indexed the first character ('B').
    2. GL.iNet GUI writes custom client names to option tag instead of option name.
    3. Unused placeholder interfaces (wwan, wwan6, secondwan, modem_*) on Flint 2 returned empty/error objects in LuCI RPC.
  • Fix Applied:
    • Created custom container entrypoint /opt/docker_container_config/openwrt-stats/custom-entrypoint.sh mounted in docker-compose.yaml to patch the string indexing bug and read tag || name.
    • Disabled unused WAN interfaces in /etc/config/network on Flint 2.
    • Installed /usr/share/rpcd/acl.d/openwrt-stats.json on both routers to grant hostapd.* and uci permissions.

2. Dual-Tagging for Local DNS (option name vs option tag) ​

  • Symptom: Static DHCP hosts had nicknames in GL.iNet web GUI, but dnsmasq could not resolve them as local hostnames (NXDOMAIN).
  • Root Cause: GL.iNet firmware uses option tag for GUI nicknames, whereas standard OpenWrt dnsmasq requires option name for local DNS A/AAAA records.
  • Fix Applied:
    • Updated all 34+ static host reservations on Flint 2 with RFC-compliant option name (e.g., pve-1, pbs, docker-admin, esp32-cam, meta-ai-glasses) while preserving option tag.

3. Archer C7 False Positive "Unauthorized VLAN Migration" Alerts ​

  • Symptom: Periodic alerts: ⚠️ Device Moved to IoT VLAN (192.168.0.2 -> 192.168.69.106) followed 5 minutes later by 🚨 Unauthorized VLAN Migration! (192.168.69.106 -> 192.168.0.2).
  • Root Cause: Archer C7's IoT bridge interface br-iot was set to proto 'dhcp'. Archer C7 requested an IP on VLAN 69 using its physical MAC (68:FF:7B:AB:93:06), received 192.168.69.106, and installed a default route via 192.168.69.1, conflicting with its static 192.168.0.2 on Main LAN.
  • Fix Applied:
    • Changed Archer C7 network.iot.proto to 'none'. (An AP bridge only passes Layer 2 frames between Wi-Fi and VLAN trunk, and must not have an IP).
    • Removed stale lease 192.168.69.106 from Flint 2.

4. iPhone "No Internet Connection" Stalls (802.11r FT Key Rejection) ​

  • Symptom: When moving between Flint 2 and Archer C7, iPhones showed full signal but orange "No Internet Connection" and dropped to 4G cellular data for 30 seconds.
  • Root Cause: ieee80211r '1' (Fast Transition) with ft_psk_generate_local failed between mixed vendor drivers (MediaTek mt7986 vs Qualcomm ath10k), logging daemon.err hostapd: phy0-ap0: nl80211: kernel reports: key addition failed. The phone associated at Layer 2 without active encryption keys in hardware, causing 100% packet loss until timeout.
  • Fix Applied:
    • Disabled ieee80211r '0' on all SSIDs on both routers.
    • Retained ieee80211k '1' (Radio Resource Measurement) for seamless AP neighbor discovery. Standard WPA2 4-way handshake completes in ~30ms without driver errors.

5. 5 GHz Channel Selection & Non-Overlapping UNII-1 Split (Ch 36 vs Ch 44) ​

  • Symptom: Wireless clients connecting to Archer C7 5GHz experienced heavy packet loss, beacon collisions, and disassociations after ~60 seconds, dropping to 2.4GHz.
  • Root Causes:
    1. Setting Archer C7 to DFS Channel 52 triggered mandatory 60s radar silence periods (DFS-CAC-START).
    2. Setting Flint 2 to Channel 36 (80MHz) and Archer C7 to Channel 44 (80MHz) put both routers on the exact same 80MHz frequency block (5180–5240 MHz, center 42). Because Flint 2 transmits Wi-Fi 6 (802.11ax) and Archer C7 transmits Wi-Fi 5 (802.11ac), the overlapping preambles caused continuous Clear Channel Assessment (CCA) blocking and packet collisions.
    3. Setting Archer C7 to UNII-3 (Channel 149) caused driver TX failures on older Qualcomm ath10k-ct firmware in the GB regulatory domain.
  • Fix Applied:
    • Configured Flint 2 5GHz on Channel 36 (HE40: 5180–5200 MHz, Center 38).
    • Configured Archer C7 5GHz on Channel 44 (VHT40: 5220–5240 MHz, Center 46).
    • Both APs operate in standard UNII-1 Non-DFS with 100% physically clean, non-overlapping channels, instant 0s boot time, and maximum hardware driver stability.

6. Post-Roaming 5-Minute Return Traffic Black Hole (Bridge Ageing Timeout) ​

  • Symptom: Client successfully associated to Archer C7, transmitted packets (RX: 700+ pkts), but received 0 return packets (TX: 5 pkts), causing iOS to fall back to 4G.
  • Root Cause: Linux kernel bridge br-lan on Flint 2 had default MAC ageing time of 300 seconds (5 minutes). When the phone roamed to Archer C7 (lan4), Flint 2 continued routing return frames (DNS, HTTP replies) to its internal wlan1 radio until the 5-minute timer expired.
  • Fix Applied:
    • Configured ageing_time '15' (15 seconds) on both Flint 2 and Archer C7 bridges (/etc/config/network).
    • Set disassoc_low_ack '0' to prevent APs from prematurely deauthenticating clients during roaming.

7. Qualcomm ath10k DHCP Multicast Corruption & APIPA 169.254.x.x Stall ​

  • Symptom: Clients connecting to Archer C7 Wi-Fi connected at Layer 2 but failed to acquire a DHCP lease, resulting in self-assigned APIPA 169.254.x.x addresses, orange "No Internet Connection" badges, and instant fallback to 4G cellular data.
  • Root Cause: Qualcomm Atheros driver (ath10k) has a known hardware/driver issue with OpenWrt's default multicast_to_unicast '1' feature. When enabled, the kernel bridge attempts to translate broadcast DHCP Offer/Ack frames into directed unicast frames. The ath10k firmware frequently drops or corrupts these translated frames, preventing wireless clients from completing the DORA transaction.
  • Fix Applied:
    • Set option multicast_to_unicast '0' on all Wi-Fi interfaces across both Flint 2 and Archer C7 in /etc/config/wireless.
    • Verified DHCP Offer packets traverse Layer 2 bridge cleanly as native broadcast frames.

8. wpad-basic-mbedtls Hostapd Syntax Error (bss_transition) ​

  • Symptom: Archer C7 Wi-Fi failed to start on reload, logging unknown configuration item 'bss_transition'.
  • Root Cause: The default OpenWrt package wpad-basic-mbedtls on Archer C7 does not compile 802.11v BSS Transition support. Adding bss_transition '1' causes hostapd to abort parsing the virtual interface configuration.
  • Fix Applied:
    • Removed option bss_transition from Archer C7 UCI configs while keeping ieee80211k '1' for RRM neighbor discovery.

9. iOS "Privacy Warning" & "Limit IP Address Tracking" Interactions ​

  • Symptom: iPhone showed "Privacy Warning" under the Wi-Fi network settings or received dynamic IP instead of static reservation.
  • Root Cause:
    1. Turning off Apple's "Private Wi-Fi Address" (MAC randomization) to use the physical hardware MAC address for static DHCP reservations triggers Apple's security prompt informing the user that the physical MAC is visible to the network. When Private MAC is enabled, iOS uses a randomized MAC (e.g. 06:6b:5b:0d:f3:db), which gets assigned a dynamic IP pool lease (192.168.0.170) instead of the static lease 192.168.0.70.
    2. Apple's "Limit IP Address Tracking" routes encrypted DNS lookups through Apple Private Relay (mask.icloud.com). When AdGuard Home or local DNS blocks Private Relay (to enforce local DNS filtering), iOS flags the network. If Private Relay cannot connect, iOS may stall or use cellular data.

10. Zigbee 2.4 GHz & Wi-Fi Coexistence Architecture (SLZB-06M) ​

  • Topology: SLZB-06M network coordinator (192.168.0.110) runs on Zigbee Channel 11 (center frequency 2405 MHz).
  • Interference Risk: Standard Wi-Fi Channel 1 (2401–2423 MHz) directly overlaps with Zigbee Channel 11 (2405 MHz).
  • Fix Applied:
    • Configured Flint 2 2.4GHz on Wi-Fi Channel 11 (2451–2473 MHz, center 2462 MHz).
    • Configured Archer C7 2.4GHz on Wi-Fi Channel 6 (2426–2448 MHz, center 2437 MHz).
    • This leaves the lower 2.4 GHz spectrum (2400–2415 MHz) 100% free of Wi-Fi traffic, giving the Zigbee network completely silent airtime with zero packet collisions or sensor drops.

11. iOS "Use Connectivity Assist" vs AdGuard Home & APIPA 169.254.x.x Failovers ​

  • Symptom: iPhone periodically disconnects from kevin-but-better, displays an APIPA self-assigned IP (169.254.103.103), and fails to route traffic over Wi-Fi, silently switching to 4G Cellular data despite being associated to the AP.
  • Root Causes:
    1. iOS "Use Connectivity Assist" (Wi-Fi Assist): When enabled, iOS actively probes Apple network telemetry and captive check endpoints (captive.apple.com, mask.icloud.com, gateway.icloud.com). Because AdGuard Home blocks telemetry and iCloud Private Relay tracking domains, iOS Connectivity Assist flags the Wi-Fi network as "broken/unreliable", tears down active IP routing over Wi-Fi, falls back to 4G cellular data, and leaves the Wi-Fi interface in a degraded APIPA state. (Apple explicitly warns under this toggle: "If you use an ad blocker, you may want to turn this off.")
    2. Sleep/Wake Multicast Delivery Lag: When the iPhone wakes up from deep 802.11 power-save sleep, standard broadcast DHCP Offers (multicast_to_unicast '0') and default multi-beacon DTIM intervals can experience slight delivery delays.
  • Fix Applied:
    • Client Configuration: Set Use Connectivity Assist: OFF in iOS Settings $\rightarrow$ Wi-Fi $\rightarrow$ kevin-but-better $\rightarrow$ (i).
    • Flint 2 Radio Tuning: Enabled multicast_to_unicast '1' and dtim_period '1' on Flint 2's MediaTek MT7986 interfaces (default_radio1, default_radio0, iot_radio0). The router converts broadcast DHCP/ARP frames into directed high-speed unicast frames with hardware ACK, delivering DHCP leases to waking phones in under 2ms. (Note: Archer C7 retains multicast_to_unicast '0' due to Qualcomm ath10k driver quirks).

📋 Best Practices: What Works vs. What Doesn't ​

Scenario / Setting❌ What Breaks (Do Not Do)✅ What Works (Follow This)
802.11r Fast RoamingEnabling ieee80211r '1' on mixed-chipset APs without synchronized R0KH/R1KH tables causes key addition failed and 30s connection blackouts.Use ieee80211r '0' + ieee80211k '1'. Standard WPA2 4-way handshake takes ~30ms and is 100% reliable across all clients.
5 GHz Channel SelectionSetting both APs to 80MHz in UNII-1 causes co-channel overlap; DFS channels cause 60s radar silence; UNII-3 causes QCA9880 driver issues.Use 40MHz Non-DFS UNII-1 split: Flint 2 on Channel 36 (HE40: 5180–5200 MHz), Archer C7 on Channel 44 (VHT40: 5220–5240 MHz).
2.4 GHz & Zigbee CoexistenceSetting Wi-Fi to Channel 1 destroys Zigbee Channel 11 (2405 MHz) reliability.Split Wi-Fi 2.4G between Channel 6 (Archer C7) and Channel 11 (Flint 2). Zigbee Channel 11 (2405 MHz) remains 100% clear.
802.11v BSS TransitionSetting bss_transition '1' on Archer C7 with wpad-basic-mbedtls crashes hostapd with syntax error.Omit bss_transition on Archer C7. Use ieee80211k '1' for client neighbor reports.
Multicast-to-UnicastEnabling multicast_to_unicast '1' on Qualcomm ath10k (Archer C7) corrupts DHCP packets. Leaving it '0' on Flint 2 slows wake-up delivery.Set multicast_to_unicast '0' on Archer C7 (ath10k). Set multicast_to_unicast '1' and dtim_period '1' on Flint 2 (mt7986).
Access Point IoT BridgeSetting proto 'dhcp' on the AP's IoT bridge assigns an IP, steals the default route, and triggers cross-VLAN migration alerts.Set option proto 'none' on the AP's IoT interface. Layer 2 frames bridge seamlessly without giving the AP an IP on untrusted VLANs.
Bridge MAC Table TimeoutDefault 300s bridge ageing time causes return packets to be sent to the old port for 5 minutes after roaming.Set option ageing_time '15' in config device for br-lan on both routers.
Client DisassociationDefault disassoc_low_ack '1' aggressively kicks roaming phones if a single ACK is dropped during handoff.Set option disassoc_low_ack '0' on all Wi-Fi interfaces in /etc/config/wireless.
DHCP ReservationsSetting only option tag in GL.iNet breaks local DNS hostname resolution in dnsmasq.Always set both option name '<hostname>' and option tag '<nickname>' in /etc/config/dhcp.
Windows Security ProfilesChanging AKM suites (FT-PSK $\leftrightarrow$ PSK) invalidates Windows cached PMK tokens, requiring a one-time password prompt.Once set to standard PSK, keep the cipher stable to prevent client-side credential prompts.
iOS Connectivity AssistLeaving "Use Connectivity Assist" ON with AdGuard Home causes iOS to fail Apple probes, switch to 4G, and show APIPA 169.254.x.x.Set "Use Connectivity Assist" to OFF and "Limit IP Address Tracking" to OFF in iOS Wi-Fi settings for home SSIDs.

Authoritative operational repository and DR hub.