Syncing WiFi CAPsMAN to Legacy CAPsMAN with a RouterOS Script
Running old wifi-qcom-ac hardware alongside newer WiFi CAPsMAN devices means maintaining two completely separate CAPsMAN systems. This script watches your new WiFi CAPsMAN config for changes and mirrors them into the legacy CAPsMAN config automatically.
What This Guide Sets Up
RouterOS ships two unrelated CAPsMAN implementations: the legacy /caps-man menu used by the old “Wireless” package and wifiwave2, and the newer /interface/wifi/capsman menu used by the wifi-qcom and wifi-qcom-ac packages. They don’t share configuration, and a CAP running one package can only ever join the matching CAPsMAN — there’s no unified system.
If you’ve got a mix of old and new access points, you end up managing SSID, security, and VLAN settings twice. This script reduces that duplication by watching the new WiFi CAPsMAN config for changes and pushing matching updates into the legacy CAPsMAN config on a schedule, so you only have to edit one side.
/interface/wifi/capsman) for wifi-qcom / wifi-qcom-ac devices, e.g. hAP ax2./caps-man) for wireless / wifiwave2 devices, e.g. hAP ac2.New WiFi CAPsMAN (cfg-main / dp-main)
│ you edit SSID / security / VLAN here
â–¼
Sync script — runs on a scheduler, checks for changes
│
└──► pushes matching settings into
Legacy CAPsMAN (cfg-main-legacy / dp-main-legacy)
Old hAP ac2 (Wireless / wifiwave2) and new hAP ax2 (wifi-qcom) each join their own CAPsMAN,
but both stay in sync with a single source of truth.
Prerequisites
/interface/wifi/capsman/caps-man/caps-man configuration, /caps-man security, /caps-man channel, /caps-man datapath). This guide syncs SSID, VLAN, and bridge as a starting point — you’ll need to extend it if you also want security/passphrase or channel settings mirrored.
Part 1 — Create the Sync Script
This script builds a fingerprint from your WiFi CAPsMAN settings and compares it to the last known value. If something changed, it updates the corresponding legacy CAPsMAN configuration and datapath.
In System > Scripts (or via terminal), create a new script with the name below and paste in the script body:
/system/script/add name=wifi-capsman-sync source={ :local wifiCfgName "cfg-main" :local wifiDpName "dp-main" :local capsCfgName "cfg-main-legacy" :local capsDpName "dp-main-legacy" # Gather current WiFi CAPsMAN config values :local wCfg [/interface/wifi/configuration get [find name=$wifiCfgName]] :local wSsid ($wCfg->"ssid") :local wSecurity ($wCfg->"security") :local wDp [/interface/wifi/datapath get [find name=$wifiDpName]] :local wVlan ($wDp->"vlan-id") :local wBridge ($wDp->"bridge") # Build a fingerprint string of the values we care about :local currentString ("$wSsid|$wSecurity|$wVlan|$wBridge") # Load previous fingerprint from a global variable :global wifiCapsManLastHash :if ([:typeof $wifiCapsManLastHash] = "nothing") do={ :set wifiCapsManLastHash "" } :if ($currentString != $wifiCapsManLastHash) do={ :log warning ("WiFi CAPsMAN config change detected. Updating legacy caps-man config...") # Update legacy CAPsMAN configuration :do { /caps-man/configuration/set [find name=$capsCfgName] ssid=$wSsid } on-error={ :log error ("Failed to update caps-man configuration $capsCfgName") } # Update legacy CAPsMAN datapath :do { /caps-man/datapath/set [find name=$capsDpName] vlan-id=$wVlan bridge=$wBridge } on-error={ :log error ("Failed to update caps-man datapath $capsDpName") } :log warning ("Legacy caps-man config sync complete.") :set wifiCapsManLastHash $currentString } else={ :log info ("No WiFi CAPsMAN config change detected.") } }
/caps-man configuration doesn’t take a raw security string — it references a named /caps-man security profile. The line above intentionally leaves security syncing out; see the Troubleshooting section for how to extend it safely for your setup.
Before scheduling it, run the script once by hand and check the logs:
/system/script/run wifi-capsman-sync
/log/print where message~"caps-man"
You should see an initial “config change detected” entry the first time it runs, since there’s no stored fingerprint yet. Confirm the legacy config values under /caps-man configuration print and /caps-man datapath print match what you expect before moving on.
Part 2 — Schedule It
Run the script on a recurring interval so changes get picked up automatically:
/system/scheduler/add name="wifi-capsman-sync-scheduler" \ interval=5m \ on-event="/system/script/run wifi-capsman-sync" \ comment="Syncs WiFi CAPsMAN changes to legacy caps-man"
/interface/wifi/configuration or /interface/wifi/datapath will be mirrored into the legacy CAPsMAN config within one scheduler interval.
Quick Reference
| Item | Value / Command |
|---|---|
| Script name | wifi-capsman-sync |
| Scheduler interval | 5m |
| WiFi CAPsMAN config | /interface/wifi/configuration print |
| WiFi CAPsMAN datapath | /interface/wifi/datapath print |
| Legacy CAPsMAN config | /caps-man/configuration print |
| Legacy CAPsMAN datapath | /caps-man/datapath print |
| Run script manually | /system/script/run wifi-capsman-sync |
| Check sync logs | /log/print where message~"caps-man" |
| Remove scheduler (to disable sync) | /system/scheduler/remove [find name="wifi-capsman-sync-scheduler"] |
Troubleshooting
Log shows “Failed to update caps-man configuration”
Almost always a name mismatch. Confirm the legacy config actually exists with that exact name:
/caps-man/configuration/print
Update the capsCfgName value at the top of the script (or the settings panel above) to match.
Sync always says “config change detected” on every run
This happens if the global variable wifiCapsManLastHash isn’t persisting between runs — usually because the router rebooted, or because the script was edited and re-added rather than just having its source updated. This is expected right after a reboot; it’ll settle down after the first run.
I want to sync security / passphrase too
Legacy CAPsMAN security lives in a separate /caps-man security menu, referenced by name from the configuration. Pull the passphrase from /interface/wifi/security get [find name=...] passphrase and push it with /caps-man/security/set [find name=...] passphrase=..., then reference that security profile from your legacy configuration. Add these values into the fingerprint string so changes there also trigger a sync.
Changes on the legacy side get overwritten unexpectedly
This is a one-way sync: WiFi CAPsMAN → legacy CAPsMAN. Any manual edit made directly under /caps-man will be overwritten the next time the script detects a change on the WiFi CAPsMAN side. Treat the WiFi CAPsMAN config as the single source of truth and make all edits there.
ac2 (legacy) still isn’t picking up the wifi
This script only keeps the two CAPsMAN configs in sync — it doesn’t affect forwarding mode. Remember that wifi-qcom-ac devices only support local forwarding, and legacy CAPsMAN devices need their own compatible forwarding setting; check that separately if wifi still isn’t coming up on the CAP.
Applies to RouterOS v7.13+ running both the legacy Wireless/wifiwave2 package and wifi-qcom/wifi-qcom-ac side by side · Guide last updated July 2026




