There are more wrong ways to configure VLANs on MikroTik than on any other platform I work with, and the internet has preserved all of them. VLAN interfaces stacked on physical ethernet ports. A separate bridge per VLAN. The old /interface ethernet switch menu from the CRS1xx/CRS2xx era. Configs that mix two of these and work by accident until a reboot reorders interface initialization.
RouterOS 7 has exactly one correct answer: a single bridge with vlan-filtering=yes, ports assigned tagged or untagged membership in a VLAN table, and — on capable hardware — the whole thing offloaded to the switch chip so the CPU never sees bridged frames. It behaves like a managed switch because, configured this way, it is one.
The reason this topic has its own article isn’t the config — it’s maybe fifteen lines. It’s that the enable step is the single most reliable way to lock yourself out of a MikroTik. The moment vlan-filtering flips to yes, every frame that doesn’t match the VLAN table is dropped, including — if you missed one line — your own management session. So we’ll build the config, then walk the migration procedure that makes lockout impossible.
The Model: One Bridge, a VLAN Table, and PVIDs
Three concepts, and the whole system falls out of them:
The bridge is your switch. All switched ports join it. With vlan-filtering=no (the default), it floods everything everywhere like a dumb switch. With vlan-filtering=yes, it consults the VLAN table for every frame.
Port VLAN membership comes in two flavors, exactly like every managed switch you’ve touched:
- Tagged (trunk): the port carries frames with 802.1Q tags intact — for links to other switches, hypervisors, and APs.
- Untagged (access): the port strips tags on egress, and untagged frames arriving on it are assigned to the port’s pvid.
The bridge itself is a port — a virtual one connecting the switch to the router’s CPU. This is the detail that makes or breaks the config. If the CPU should participate in a VLAN (route it, serve DHCP on it, be managed over it), the bridge must be a tagged member of that VLAN in the VLAN table. Forget this and the data plane works perfectly while the router itself becomes unreachable — the classic symptom of “my VLANs work but I can’t ping the gateway.”
Building It
Scenario: ether2 is a trunk to a hypervisor, ether3–ether5 are access ports for users (VLAN 10), ether6 is an access port for a printer VLAN (20), and management lives on VLAN 99.
# 1. The one bridge. Do not enable vlan-filtering yet./interface bridgeadd name=bridge1 vlan-filtering=no comment="main switch"
# 2. Ports join the bridge. Access ports get their pvid here./interface bridge portadd bridge=bridge1 interface=ether2 comment="trunk to hypervisor" \ frame-types=admit-only-vlan-tagged ingress-filtering=yesadd bridge=bridge1 interface=ether3 pvid=10 \ frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yesadd bridge=bridge1 interface=ether4 pvid=10 \ frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yesadd bridge=bridge1 interface=ether5 pvid=10 \ frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yesadd bridge=bridge1 interface=ether6 pvid=20 \ frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes
# 3. The VLAN table: who carries what, tagged or untagged.# Note bridge1 itself tagged on every VLAN the CPU needs./interface bridge vlanadd bridge=bridge1 vlan-ids=10 tagged=bridge1,ether2 untagged=ether3,ether4,ether5add bridge=bridge1 vlan-ids=20 tagged=bridge1,ether2 untagged=ether6add bridge=bridge1 vlan-ids=99 tagged=bridge1,ether2
# 4. L3 interfaces for the VLANs the router routes, on top of the bridge/interface vlanadd interface=bridge1 vlan-id=10 name=vlan10-usersadd interface=bridge1 vlan-id=20 name=vlan20-printadd interface=bridge1 vlan-id=99 name=vlan99-mgmt
/ip addressadd address=10.0.10.1/24 interface=vlan10-usersadd address=10.0.20.1/24 interface=vlan20-printadd address=10.0.99.1/24 interface=vlan99-mgmtNote where things attach: /interface vlan interfaces sit on bridge1, never on ether2 directly. Putting a VLAN interface on a physical port that’s also a bridge member is the classic broken hybrid — traffic bypasses the bridge VLAN table and you get asymmetric weirdness that only shows under load.
Two parameters deserve their defaults challenged into explicitness:
ingress-filtering=yes(the default in v7): the port drops tagged frames for VLANs it isn’t a member of. There’s no good reason to turn this off; without it, any host can inject into any VLAN it can name — VLAN hopping as a configuration choice.frame-types:admit-only-vlan-taggedon trunks (no untagged sneaking onto pvid 1),admit-only-untagged-and-priority-taggedon access ports (no tagged injection from user desks). The permissive defaultadmit-allis for hybrid ports, which you should use rarely and comment loudly.
Notice we have not enabled vlan-filtering yet. That’s the migration section, and the order is the whole point.
Hardware Offload: Getting the Switch Chip to Do the Work
On devices with a switch chip, bridging can happen in silicon — the CPU never touches forwarded frames. Bridge ports show an H flag when hardware offload is active:
/interface bridge port print# Flags: H - HW-OFFLOADHere’s the catch that defines MikroTik hardware selection: enabling vlan-filtering=yes disables hardware offload on chips that can’t do VLAN filtering in hardware, silently dropping all bridging to the CPU. On a ten-port device pushing wire speed, that’s the difference between a switch and a space heater.
Per MikroTik’s documentation, bridge VLAN filtering with hardware offload works on devices with Marvell Prestera switch chips (the CRS3xx and CRS5xx lines) and, since RouterOS v7, on several more chips: RTL8367, 88E6393X, 88E6191X, 88E6190, MT7621, MT7531, and EN7523 — which covers most current hEX and hAP models. Older or cheaper devices outside these families must either accept CPU bridging or use the legacy switch-menu VLAN method.
Check what you have before you design around it:
/interface ethernet switch printAnd after enabling vlan-filtering, verify the H flags are still present on /interface bridge port print. If they vanished, your chip doesn’t offload VLAN filtering, and you need to decide whether CPU throughput is acceptable for your traffic profile. Don’t guess — test with /tool bandwidth-test between ports and watch /system resource cpu print.
One more offload note: fasttrack’s hw-offload=yes (from the firewall article) and L3HW offloading on CRS3xx/CCR2xxx are separate mechanisms from bridge offload. Bridge offload is about switched frames; the others accelerate routed flows. A CRS326 doing pure VLAN switching with offload will do line rate all day; ask its CPU to route between VLANs and you’ll meet its 800 MHz reality quickly.
The Lockout, and the Migration That Avoids It
The trap, mechanically: you’re managing the router over a port that’s a bridge member. You enable vlan-filtering=yes. Your management traffic is untagged, landing in pvid 1 — but VLAN 1 has no entry in the VLAN table, or the bridge isn’t a member, so the bridge drops every frame from your session, including the one carrying your frantic attempt to undo the change. On a remote site, that’s a truck roll.
The procedure that makes this a non-event:
Step 0 — have a rescue path. Know your out-of-band option before you start: serial console, or MAC-WinBox allowed on a LAN interface (/tool mac-server mac-winbox set allowed-interface-list=LAN — this works even when IP is broken), or physical access. If the device is remote and you have none of these, schedule /system reboot in 10 minutes via scheduler as a dead-man switch, and disable it after success.
Step 1 — build everything with filtering off. All bridge ports, the complete VLAN table, the management VLAN interface and its IP address — exactly as in the section above, with vlan-filtering=no. Nothing you add here disrupts traffic; the table is simply not consulted yet.
Step 2 — move your management session onto the future management VLAN. Connect to 10.0.99.1 over a port and path that will be valid after filtering is on (e.g., tagged VLAN 99 over the trunk, or set your access port’s pvid to 99). Confirm the session works. This is the step people skip and regret: you’re proving the post-change topology while the pre-change one still carries you.
Step 3 — enable, inside Safe Mode. In the CLI, press Ctrl+X to enter Safe Mode — RouterOS’s dead-man switch. If your session dies after a change, everything done in Safe Mode automatically rolls back.
# In an SSH session: Ctrl+X first ([Safe Mode taken] appears)/interface bridge set bridge1 vlan-filtering=yes# Session still alive? Ctrl+X again to commit and release Safe Mode.# Session dead? Wait ~9 minutes for TCP timeout; config reverts on its own.Safe Mode plus a pre-verified management path turns the scariest command in RouterOS into a routine change. I’ve done this migration on production switches over lunch; the procedure, not courage, is what makes that reasonable.
Verification
The VLAN table has a print that shows both configured and learned state:
# Current VLAN membership - dynamic entries show what pvid settings generated/interface bridge vlan print
# Which MACs learned on which VLAN - the ground truth of your switching/interface bridge host print where bridge=bridge1
# Per-port state: pvid, frame-types, and the H flag for offload/interface bridge port print detailThen test the failure cases, not just the happy path: plug an untagged host into the trunk port (should get nothing — admit-only-vlan-tagged), tag VLAN 20 frames from a user access port (should be dropped by ingress filtering), and confirm inter-VLAN traffic actually transits the router where your firewall can see it — /tool sniffer quick interface=vlan10-users while pinging from VLAN 20 shows you routed packets, which is exactly what you want: switched inside a VLAN, routed and filtered between them.
Closing Thoughts
One bridge. VLAN table with the bridge itself tagged on every CPU-facing VLAN. Ingress filtering on, frame-types strict, VLAN interfaces on the bridge only. Verify hardware offload survived. Migrate with a rescue path and Safe Mode. That’s the entire discipline, and it’s identical in shape to how you’d configure any enterprise switch — RouterOS just makes the wrong ways available too.
If you’re carrying these VLANs to a VyOS router upstream, the VyOS Guide covers the equivalent bridge and VLAN config on that side; the tagging decisions made here dictate what arrives there. Next in this series: DHCP and DNS — putting a server on each of those shiny new VLAN interfaces, and why the DNS half must never face the WAN.