Asus ZenWiFi XT8 VLAN/SSID Bridge Script (Asuswrt-Merlin / Gnuton)
I really wanted working VLANs on my Asus ZenWiFi XT8 mesh setup and as I couldn't find any good ones the only alternative was to make one. I'm not a coder but I'm stubborn and I love to read up and learn new stuff. So I sat down with Google, ChatGPT and a lot of coffee for two weeks and after a lot of trial and error I finally got (as far as I know) a working VLAN script.How it works
The same SSID (e.g., MyMain5G1) can live on different internal interfaces on the Main vs Node (base radio on the main unit, VAP slot on a node). When I hard-code interface names, it worked on one box, then failed on the other.Instead, the script maps SSID name -> VLAN:
- You write SSID:VLAN exactly as seen in the GUI (e.g., r80xcore-wifi-IoT:20).
- The script finds the right interface (base radio or .1/.2/.3 VAP) and attaches it to the right bridge.
- Result: the same config works on Main and Nodes, regardless of how AiMesh places the interfaces.
- switch: tested & working (recommended)
- daisy-chain: experimental (use daisy_trunk_helper to mark a LAN port as trunk on the main unit)
- wireless backhaul: VLANs only on the main unit (nodes can’t carry multiple tagged SSIDs over wireless backhaul)
Installation
1. Enable JFFS custom scripts in the web GUI.2. Ensure JFFS is on:
Code:
nvram get jffs2_on # should print 1
nvram get jffs2_scripts # should print 1
# If not:
nvram set jffs2_on=1
nvram set jffs2_scripts=1
nvram commit
reboot
3. Install the script (on both main + nodes):
Code:
nano /jffs/scripts/vlan_manager.sh
Code:
chmod +x /jffs/scripts/vlan_manager.sh
In the script, set: PERSISTENT="no" (no nvram commit) and optionally DRY_RUN="yes" (preview actions).
Then run:
Code:
sh /jffs/scripts/vlan_manager.sh
Code:
/jffs/scripts/vlan_manager.sh >> /jffs/scripts/vlan_manager.log 2>&1
tail -n 100 /jffs/scripts/vlan_manager.log
5. Enable auto-run on boot (copy whole block):
Code:
echo 'Creating /jffs/scripts/services-start hook'
cat > /jffs/scripts/services-start <<'EOF'
#!/bin/sh
LOG="/jffs/scripts/vlan_manager.log"
MAX=65536
KEEP=$((MAX/2))
# trim the log if needed
if [ -f "$LOG" ]; then
SIZE=$(wc -c < "$LOG" 2>/dev/null || echo 0)
if [ "$SIZE" -gt "$MAX" ]; then
tail -c "$KEEP" "$LOG" > "$LOG.tmp" && mv "$LOG.tmp" "$LOG"
fi
fi
# --- Daisy-chain helper (optional) ---
# To enable, remove the leading '#' on BOTH lines below:
#sleep 10
#[ -x /jffs/scripts/daisy_trunk_helper.sh ] && /jffs/scripts/daisy_trunk_helper.sh >> "$LOG" 2>&1
# Apply VLAN/SSID bridges
# Use 20s normally; if you enabled the daisy helper above, make this 10s
sleep 20
/jffs/scripts/vlan_manager.sh >> "$LOG" 2>&1
EOF
chmod +x /jffs/scripts/services-start
Reboot, then check the logs if you want:
Code:
tail -n 100 /jffs/scripts/vlan_manager.log
Notes
- br0 stays management/native; the script never deletes br0.
- Only Guest 1 per band (2.4/5-1/5-2) is mesh-capable. Guest 2/3 on all bands lives on the main unit.
- On your switch, make each XT8 WAN (eth0) port a trunk carrying your VLANs. On your firewall (e.g., OPNsense), create VLAN interfaces, IP/DHCP, and allow DHCP/DNS in rules.
- To configure daisy-chain, set DAISY_PORT="ethX" (in /jffs/scripts/daisy_trunk_helper.sh) where X is the port you connect the node on (1,2 or 3). Then add the script to services-start, preferably before the vlan script.
Feedback
If something looks off, please post logs from "vlan_manager.log".Hope someone have any use of this! If you test Daisy-chain, please report back!
Changelog
0.40 first public test release.0.41 added and edited how-to in scripts to make it clearer. Added log trimming.
To-do
* work on the daisy-chain script. I hope to get some logs to see if it's working or not.* make the script auto-configure on nodes, that way you only setup everything once on the main. If you do any changes, those are pushed to the other unit/units.
* see if it's possible to extend the use to other units.
Attachments
Last edited: