Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Multi SSID with VLAN script, for ASUS AC3100 with Merlin
#!/bin/sh
# references
# NVRAM reference = https://wiki.dd-wrt.com/wiki/index.php/Switched_Ports
# Original Script Reference = https://gist.github.com/Jimmy-Z/6120988090b9696c420385e7e42c64c4
# Forked Script Reference = https://gist.github.com/tubaxiaosiji/d6c969797e470aa3eadfbfd6a966aa60
# This Script = https://gist.github.com/b1tman1ac/3d2cad0094e78a587f217a0720c9c11c
# multi SSID with VLAN script, for ASUS AC3100(4 port model + WAN port) with Merlin
#
# setup before hand: (if moving between firmware you are encouraged to always do a factory reset)
# 1. set "router" to "AP Mode"
# - this will put all ports and wireless in br0
# 2. create 1 guest network
# 3. enable Administration => System => Enable JFFS custom scripts and configs
# 4. put this script in /jffs/scripts/, name should be "services-start"
# 5. remember `chmod a+x services-start`
# Note :: I strongly suggest you use static IP instead of DHCP
# (In my test, the "router" will pickup DHCP lease from VLAN 1 instead of VLAN 11)
# 6. reboot
# some basic info of the original AP mode:
# exec 'brctl show' shell command, then you will get info like below :
#
# bridge name bridge id STP enabled interfaces
# br0 8000.2c56dc553730 no vlan1
# wl0.1
# wl1.1
# exec 'ip a' or 'ifconfig', mapping of interfaces from default are as follows :
#
# vlan1 => Set of Switch ports, router on ap mode, vlan1 members include switch ports 0 1 2 3 4 5 7 8t as defined by Robocfg (see below)
# br0 => default bridge
# eth0 => WAN port
# eth1 => Default WiFi 2.4G Radio
# eth2 => Default WiFi 5G Radio
# wl0.1, wl0.2 => Guest [1|2|3] Wifi 2.4G Radio
# wl1.1, wl1.2 => Guest [1|2|3] Wifi 5G Radio
# exec 'robocfg show' in shell can show switch ports and vlans(switch inside only, Not on linux)
# Robocfg port mapping to physical ports (confirm yourself via 'robocfg show' command & plugging and unplugging cables in the ports)
# Model { WAN L1 L2 L3 L4 CPU } (Physical Ports)
# RTN16: { 0, 4, 3, 2, 1, 8 } (Robocfg ports)
# RTAC56U: { 4, 0, 1, 2, 3, 5 } (Robocfg ports)
# RTN66U: { 0, 1, 2, 3, 4, 8 } (Robocfg ports)
# RTAC66U: { 0, 1, 2, 3, 4, 8 } (Robocfg ports)
# RTAC68U: { 0, 1, 2, 3, 4, 5 } (Robocfg ports)
# RTAC87U: { 0, 5, 3, 2, 1, 7 } (Robocfg ports)
# RTAC3200: { 0, 4, 3, 2, 1, 5 } (Robocfg ports)
# RTAC3100: { 4, 3, 2, 1, 0, 8 } (Robocfg ports)
# Notice: all traffic is transport by eth0(switch's Port 8) to linux(merlin system)
# # robocfg show
# Switch: enabled
# Port 0: DOWN enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 1: DOWN enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 2: DOWN enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 3: DOWN enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 4: 1000FD enabled stp: none vlan: 1 jumbo: off mac: 50:06:ab:56:ad:2f
# Port 5: 1000FD enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 7: 1000FD enabled stp: none vlan: 1 jumbo: off mac: 00:00:00:00:00:00
# Port 8: 1000FD enabled stp: none vlan: 2 jumbo: off mac: 2c:56:dc:55:37:30
# VLANs: BCM5301x enabled mac_check mac_hash
# 1: vlan1: 0 1 2 3 4 5 7 8t
# 2: vlan2: 8u
# nvram default switch config
# # nvram show | grep vlan.*hwname | sort
# vlan1hwname=et2
# vlan2hwname=et2
# # nvram show | grep port.*vlans | sort
# should be nothing by default
# # nvram show | grep vlan.*ports | sort
# vlan1ports=0 1 2 3 4 5 7 8*
# vlan2ports=8u
# # nvram show | egrep "(br|lan|w).*_ifname" | sort
# br0_ifname=br0
# br0_ifnames=vlan1 wl0.1 wl1.1
# lan_ifname=br0
# lan_ifnames=vlan1 eth1 eth2 wl0.1 wl1.1
# wan0_ifname=eth0
# wan0_pppoe_ifname=
# wan1_pppoe_ifname=
# wan_ifname2=
# wan_ifname=
# wan_ifnames=eth0
# wl0.1_ifname=wl0.1
# wl0.2_ifname=wl0.2
# wl0.3_ifname=wl0.3
# wl0_ifname=eth1
# wl1.1_ifname=wl1.1
# wl1.2_ifname=wl1.2
# wl1.3_ifname=wl1.3
# wl1_ifname=eth2
# wl_ifname=eth1
# wl_ifnames=eth1 eth2
# This setup:
# WAN(Robocfg Port 4|eth0) will be trunk/tagged port
# CPU(Robocfg Port 8) MUST be trunk/tagged port
# Bridge 0 = br0 = vlan 1, vlan 11
# Bridge 1 = br1 = Guest Wifi(wl0.1, wl1.1), vlan 12
# Vlan 11 = LAN ports (Physical Ports 1-4), Primary Wifi(eth1, eth2) & Tagged on Wan/Eth0
# Vlan 12 = Tagged on Wan/Eth0
# example traffic flow for Guest Wifi 2.4G to Internet
# client_traffic --> 2.4ghz network(wl0.1)--> br1 --> linux interface vlan12 --> switch's Port 8(tagged) -->
# --->switch's Port 4(tagged)---->up Link Port---->INTERNET
# example traffic flow for Default Wifi 5G to Internet
# client_traffic --> 5ghz network(eth2)--> linux interface vlan1 --> br0 --> linux interface vlan11 --> switch's Port 8(tagged) -->
# --->switch's Port 4(tagged)---->up Link Port---->INTERNET
# Let's get started!
#!/bin/sh
# start pre-checks and log
echo "============== START PRE-CHECKS $(date) ==================" >> /jffs/scripts/log
echo "# ip a" >> /jffs/scripts/log
ip a >> /jffs/scripts/log
echo "# ip r" >> /jffs/scripts/log
ip r >> /jffs/scripts/log
echo "# robocfg show" >> /jffs/scripts/log
robocfg show >> /jffs/scripts/log
echo "# brctl show" >> /jffs/scripts/log
brctl show >> /jffs/scripts/log
echo "# nvram show | grep vlan.*ports | sort" >> /jffs/scripts/log
nvram show | grep vlan.*ports | sort >> /jffs/scripts/log
echo "# nvram show | grep port.*vlans | sort" >> /jffs/scripts/log
nvram show | grep port.*vlans | sort >> /jffs/scripts/log
echo "# nvram show | grep vlan.*hwname | sort " >> /jffs/scripts/log
nvram show | grep vlan.*hwname | sort >> /jffs/scripts/log
echo "# nvram show | egrep \"(br|lan|w).*_ifname \"| sort" >> /jffs/scripts/log
nvram show | egrep "(br|lan|w).*_ifname" | sort >> /jffs/scripts/log
echo "============== END PRE-CHECKS $(date) ==================" >> /jffs/scripts/log
# echo $PATH > /tmp/script_debug
# start implementation and log
echo "============== START IMPLEMENTATION $(date) ==================" >> /jffs/scripts/log
# configure vlans on switch ports
# robocfg is Broadcom BCM5325/535x/536x/5311x switch configuration utility
# Below is port mapping for AC3100 (4t=wan-tagged, 8t=cpu-tagged), port mapping for others is above.
echo "# robocfg vlan 11 ports \"0 1 2 3 4t 5 7 8t\"" >> /jffs/scripts/log
robocfg vlan 11 ports "0 1 2 3 4t 5 7 8t" >> /jffs/scripts/log
echo "# robocfg vlan 12 ports \"4t 8t\"" >> /jffs/scripts/log
robocfg vlan 12 ports "4t 8t" >> /jffs/scripts/log
# add vlan interface on merlin at eth0[switch 8 Port]
echo "# vconfig add eth0 11" >> /jffs/scripts/log
vconfig add eth0 11 >> /jffs/scripts/log
echo "# vconfig add eth0 12" >> /jffs/scripts/log
vconfig add eth0 12 >> /jffs/scripts/log
# then up it
echo "# ifconfig vlan11 up" >> /jffs/scripts/log
ifconfig vlan11 up >> /jffs/scripts/log
echo "# ifconfig vlan12 up" >> /jffs/scripts/log
ifconfig vlan12 up >> /jffs/scripts/log
# remove interfaces we're gonna move to other bridges
echo "# brctl delif br0 wl0.1" >> /jffs/scripts/log
brctl delif br0 wl0.1 >> /jffs/scripts/log
echo "# brctl delif br0 wl1.1" >> /jffs/scripts/log
brctl delif br0 wl1.1 >> /jffs/scripts/log
# reconfigure br0, private LAN
echo "# brctl addif br0 vlan11" >> /jffs/scripts/log
brctl addif br0 vlan11 >> /jffs/scripts/log
# set up br1, guest LAN
echo "# brctl addbr br1" >> /jffs/scripts/log
brctl addbr br1 >> /jffs/scripts/log
echo "# brctl addif br1 vlan12" >> /jffs/scripts/log
brctl addif br1 vlan12 >> /jffs/scripts/log
echo "# brctl addif br1 wl0.1" >> /jffs/scripts/log
brctl addif br1 wl0.1 >> /jffs/scripts/log
echo "# brctl addif br1 wl1.1" >> /jffs/scripts/log
brctl addif br1 wl1.1 >> /jffs/scripts/log
echo "# ip link set br1 up" >> /jffs/scripts/log
ip link set br1 up >> /jffs/scripts/log
# setting nvram values must be correct. if NOT correct, will reject wireless client request
echo "# nvram set br0_ifname=\"br0\"" >> /jffs/scripts/log
nvram set br0_ifname="br0" >> /jffs/scripts/log
echo "# nvram set lan_ifname=\"br0\"" >> /jffs/scripts/log
nvram set lan_ifname="br0" >> /jffs/scripts/log
echo "# nvram set br0_ifnames=\"vlan1 eth1 eth2 vlan11\"" >> /jffs/scripts/log
nvram set br0_ifnames="vlan1 eth1 eth2 vlan11" >> /jffs/scripts/log
echo "# nvram set lan_ifnames=\"vlan1 eth1 eth2 vlan11\"" >> /jffs/scripts/log
nvram set lan_ifnames="vlan1 eth1 eth2 vlan11" >> /jffs/scripts/log
echo "# nvram set lan1_ifnames=\"vlan12 wl0.1 wl1.1\"" >> /jffs/scripts/log
nvram set lan1_ifnames="vlan12 wl0.1 wl1.1" >> /jffs/scripts/log
echo "# nvram set lan1_ifname=\"br1\"" >> /jffs/scripts/log
nvram set lan1_ifname="br1" >> /jffs/scripts/log
echo "# nvram set br1_ifname=\"br1\"" >> /jffs/scripts/log
nvram set br1_ifname="br1" >> /jffs/scripts/log
echo "# nvram set br1_ifnames=\"vlan12 wl0.1 wl1.1\"" >> /jffs/scripts/log
nvram set br1_ifnames="vlan12 wl0.1 wl1.1" >> /jffs/scripts/log
# we do NOT issue `nvram commit` here since it won't survive reboot anyway
echo "# killall eapd" >> /jffs/scripts/log
killall eapd >> /jffs/scripts/log
echo "# eapd" >> /jffs/scripts/log
eapd >> /jffs/scripts/log
# Flush ebtables --> clear all rules
echo "# ebtables -F" >> /jffs/scripts/log
ebtables -F >> /jffs/scripts/log
echo "============== END IMPLEMENTATION $(date) ==================" >> /jffs/scripts/log
# start verifications and log
echo "============== START VERIFICATIONS $(date) ==================" >> /jffs/scripts/log
echo "# ip a" >> /jffs/scripts/log
ip a >> /jffs/scripts/log
echo "# ip r" >> /jffs/scripts/log
ip r >> /jffs/scripts/log
echo "# robocfg show" >> /jffs/scripts/log
robocfg show >> /jffs/scripts/log
echo "# brctl show" >> /jffs/scripts/log
brctl show >> /jffs/scripts/log
echo "# nvram show | grep vlan.*ports | sort" >> /jffs/scripts/log
nvram show | grep vlan.*ports | sort >> /jffs/scripts/log
echo "# nvram show | grep port.*vlans | sort" >> /jffs/scripts/log
nvram show | grep port.*vlans | sort >> /jffs/scripts/log
echo "# nvram show | grep vlan.*hwname | sort" >> /jffs/scripts/log
nvram show | grep vlan.*hwname | sort >> /jffs/scripts/log
echo "# nvram show | egrep \"(br|lan|w).*_ifname\" | sort" >> /jffs/scripts/log
nvram show | egrep "(br|lan|w).*_ifname" | sort >> /jffs/scripts/log
echo "============== END VERIFICATIONS $(date) ==================" >> /jffs/scripts/log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment