hAP ax^2 as AP - add ethernet port to VLAN

Hi Mikrotik gurus,

I’m having some very difficult times with setting up my network with using VLANs.
I’ve managed to set it up almost completely but one last thing seems I can’t figure out.

My main router is a 3011UiAS which connects to WAN via PPPoE.
I’m running v6 RoS because I need gigabit WAN speed and I could only achieve it with v6. Tried with v7 but could never get it to work properly, reaching about 5-600 Mbps tops speed if I remember correctly.

My APs are AXes with WiFi6 running v7 and I manage them with CAPsMAN.
Because I’m running v6 on my main router, I can’t run CAPsMAN there on it (while I was running v7 on it, it was CAPsMAN too - but recently I downgraded due to performance issues I mentioned above).

So I chosen the cAP AX as my CAPsMAN as it’s the most performant of them.
I have 3 WiFi networks. Default is running vlan 1, IoT vlan 3 and guest vlan 99.
All is working properly on the WiFi side. All vlans seem to work correctly.

My problem is with the living AP (hAP AX^2) to which I have a smart TV connected which I want to be a part of the the IoT vlan (port ether2 to vlan 3).
I do not know how to do that.

Here’s a quick drawing of my network:
network.png
I’m attaching the stripped down configuration of the routers.
Main:

# sep/29/2024 21:21:53 by RouterOS 6.49.17
# model = RouterBOARD 3011UiAS
/interface bridge
add name=bridge-LAN
/interface ethernet
set [ find default-name=ether1 ] name=ether1-WAN
set [ find default-name=ether9 ] comment=OUTSIDE
set [ find default-name=ether10 ] comment="AP LIVING"

/interface vlan
add interface=bridge-LAN name=vlan-GUEST vlan-id=99
add interface=bridge-LAN name=vlan-IoT vlan-id=3
add interface=bridge-LAN name=vlan-Local-Only vlan-id=100

/interface ethernet switch port
set 5 default-vlan-id=3 vlan-mode=secure
set 6 default-vlan-id=1 vlan-mode=secure
set 7 default-vlan-id=1 vlan-mode=secure
set 8 default-vlan-id=1 vlan-mode=secure
set 9 default-vlan-id=1 vlan-mode=secure
set 11 default-vlan-id=1 vlan-mode=secure

/ip pool
add name=pool-LAN ranges=10.100.98.1-10.100.98.250
add name=pool-GUEST ranges=10.100.99.100-10.100.99.250
add name=pool-IoT ranges=10.100.3.10-10.100.3.250

/ip dhcp-server
add address-pool=pool-LAN interface=bridge-LAN name=dhcp-LAN
add address-pool=pool-GUEST interface=vlan-GUEST name=dhcp-GUEST
add address-pool=pool-IoT interface=vlan-IoT name=dhcp-IoT

/interface bridge port
add bridge=bridge-LAN interface=ether6
add bridge=bridge-LAN interface=ether8
add bridge=bridge-LAN interface=ether9
add bridge=bridge-LAN interface=ether10
add bridge=bridge-LAN interface=ether7
add bridge=bridge-LAN interface=ether2
add bridge=bridge-LAN interface=ether3
add bridge=bridge-LAN interface=ether4
add bridge=bridge-LAN interface=ether5

/interface ethernet switch vlan
add independent-learning=yes ports=ether7,ether8,ether9,ether10,switch2-cpu \
    switch=switch2 vlan-id=1
add independent-learning=yes ports=ether6,ether9,ether10,switch2-cpu switch=\
    switch2 vlan-id=3
add independent-learning=yes ports=ether9,ether10,switch2-cpu switch=switch2 \
    vlan-id=99

/ip address
add address=10.100.99.254/24 interface=vlan-GUEST network=10.100.99.0
add address=10.100.0.1/20 interface=bridge-LAN network=10.100.0.0
add address=10.100.1.254/24 interface=bridge-LAN network=10.100.1.0
add address=10.100.3.254/24 interface=vlan-IoT network=10.100.3.0

hAP ax^2:

# 2024-09-29 21:10:14 by RouterOS 7.16
# model = C52iG-5HaxD2HaxD
# serial number = HE508TXB84J
/interface bridge
add admin-mac=48:A9:8A:64:F0:FC auto-mac=no comment=defconf name=bridge
/interface ethernet
set [ find default-name=ether1 ] comment=LAN
set [ find default-name=ether2 ] comment=TV
set [ find default-name=ether3 ] comment=<free>
set [ find default-name=ether4 ] comment=<free>
set [ find default-name=ether5 ] comment=<free>
/interface wifi datapath
add bridge=bridge comment=defconf disabled=no name=capdp
/interface wifi
# managed by CAPsMAN
# mode: AP, SSID: GME, channel: 5500/ax/Ceee
set [ find default-name=wifi1 ] configuration.manager=capsman datapath=capdp \
    disabled=no
# managed by CAPsMAN
# mode: AP, SSID: GME, channel: 2442/ax/eC
set [ find default-name=wifi2 ] configuration.manager=capsman datapath=capdp \
    disabled=no
/interface bridge port
add bridge=bridge comment=defconf interface=ether1
add bridge=bridge comment=defconf interface=ether2 pvid=3
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
/interface wifi cap
set discovery-interfaces=bridge enabled=yes slaves-datapath=capdp
/ip dhcp-client
add comment=defconf interface=bridge
/system identity
set name="GME AP Living"

cAP ax:

# 2024-09-29 21:13:21 by RouterOS 7.16
# model = cAPGi-5HaxD2HaxD
/interface bridge
add admin-mac=D4:01:C3:FA:34:E9 auto-mac=no comment=defconf name=bridge \
    port-cost-mode=short
/interface wifi datapath
add bridge=bridge client-isolation=yes name="GME IoT" vlan-id=3
add bridge=bridge client-isolation=yes name="GME Guest" vlan-id=99
add bridge=bridge name=GME

/interface wifi configuration
add country=Romania datapath="GME IoT" name="GME IoT"
add country=Romania datapath="GME Guest" name="GME Guest"
add country=Romania datapath=GME name=GME

/interface wifi
add configuration=GME configuration.mode=ap name=ap-Living-2G
add configuration="GME Guest" configuration.mode=ap master-interface=ap-Living-2G name=ap-Living-2G-Guest
add configuration="GME IoT" configuration.mode=ap master-interface=ap-Living-2G name=ap-Living-2G-IoT
add configuration=GME configuration.mode=ap name=ap-Living-5G
add configuration="GME Guest" configuration.mode=ap master-interface=ap-Living-5G name=ap-Living-5G-Guest
add configuration="GME IoT" configuration.mode=ap master-interface=ap-Living-5G name=ap-Living-5G-IoT
set [ find default-name=wifi2 ] configuration=GME configuration.mode=ap name=ap-Terrace-2G
add configuration="GME Guest" configuration.mode=ap master-interface=ap-Terrace-2G name=ap-Terrace-2G-Guest
add configuration="GME IoT" configuration.mode=ap master-interface=ap-Terrace-2G name=ap-Terrace-2G-IoT
set [ find default-name=wifi1 ] configuration=GME configuration.mode=ap name=ap-Terrace-5G
add configuration="GME Guest" configuration.mode=ap master-interface=ap-Terrace-5G name=ap-Terrace-5G-Guest
add configuration="GME IoT" configuration.mode=ap master-interface=ap-Terrace-5G name=ap-Terrace-5G-IoT
add configuration=GME configuration.mode=ap name=ap-Workshop-2G
add configuration="GME IoT" configuration.mode=ap master-interface=ap-Workshop-2G name=ap-Workshop-2G-IoT

/interface bridge port
add bridge=bridge comment=defconf interface=ether1 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf interface=ether2 internal-path-cost=10 path-cost=10

/interface wifi cap
set discovery-interfaces=bridge slaves-datapath=*1
/interface wifi capsman
set enabled=yes interfaces=bridge package-path="" require-peer-certificate=no upgrade-policy=none
/interface wifi provisioning
add action=create-enabled master-configuration=GME slave-configurations="GME Guest,GME IoT" supported-bands=""
/ip dhcp-client
add comment=defconf interface=bridge

/system identity
set name="GME AP Terrace"

Well generally speaking do not use vlan1, change that to vlan10 for your sanity.
There should be no issue have the hapax3 running capsman but be aware the configuration when using it to run capsman is different than before when it wasnt.
Too complex for me but search some threads in the wifi forum and you should find examples of what do to.

Not familiar with the old RB3011 but do you need to define switch ports when using bridge vlan filtering?
Also where is the management vlan on the RB3011??

VLAN is really a hard topic for me to grasp, I had weeks until I managed to get it working in the current stage (had alot of trials and errors).
I’ve read indeed that vlan1 is to be avoided but I don’t really know how to avoid it and have all things working.
Seems that all is working ok with using vlan1, and I’m actually using that as the management vlan (as far I understand it).
Once I get the problem in this topic fixed the next task would be to get rid of the vlan1 - but one thing at a time.


All that is working just fine for me. So my wifi capsman with vlans is running just fine on the cAP ax. All wifi clients are assigned the corrent vlan depending on the connected wifi.


I’m using the hw-offload vlan method https://help.mikrotik.com/docs/display/ROS/Basic+VLAN+switching#BasicVLANswitching-Otherdeviceswithabuilt-inswitchchip for RB3011, not bridge vlan-filtering.


So, my problem is with getting an ethernet port of one of my APs to the correct VLAN, not with the WiFi.

On hAP ax2 you’ll have to enable vlan-filtering on bridge, without it PVID setting does nothing. Then you’ll have to configure ether1 as trunk port, configuration should more or less mirror of ether10 on RB3011. But you’ll gave to use /interface/bridge and subtree hence forth.

Thanks, I’ll try that and get back.
One thing I do not understand though, is why the VLANs work just fine for the wifi interfaces on hAP ax2 but not for ether interfaces.
As you mentioned, bridge vlan-filtering is not enabled, but still the vlans on the wifi interfaces reach my main RB3011 router.
bridge.png
bridge_ports.png

On cAP ax you have

/interface wifi datapath
add bridge=bridge client-isolation=yes name=“GME IoT” > vlan-id=3

(and similar for “GME guest” datapath).

and that setting allows wifi driver to tag/untag frames by itself (without any intervention by bridge). Just as does switch chip on your RB3011. Note: not all wifi drivers can do it (wifi-qcom-ac can’t).

But for wired ethernet port hAP ax2 doesn’t provide any means for dealing with VLAN tags other than enabling vlan-filtering on bridge.

And bridge, without vlan-filtering enabled, doesn’t care about VLAN tags at all. It only forwards frames between ports without regard to VLAN tag … which means that VLAN tag will arrive at destination intact … and it also means that VLAN-based separation between VLANs is not there if bridge is VLAN-ignorant … it will forward frames through “wrong” ports if it doesn’t know the correct destination port (or if frame is sent to broadcast address which wouldn’t pass VLAN barriers if things were enabled correctly). Etc.

Thanks mkx. By enabling vlan-filtering on the bridge and configuring ether1 as trunk, it now works.

Here’s my bridge setup:

/interface bridge
add name=bridge vlan-filtering=yes
/interface bridge port
add bridge=bridge comment=defconf interface=ether1
add bridge=bridge comment=defconf interface=ether2 pvid=3
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
/interface bridge vlan
add bridge=bridge tagged=bridge,ether1 vlan-ids=3,99

And the VLANs look like this:
bridge_vlans.png

According to setup shown, ether2 should be part of VLAN 3 as well (probably as dynamic member with comment set to “added by pvid”), but it’s not shown in the screenshot. I wonder why’s that? Perhaps it gets added when ether2 gets up (something active is plugged in) … or is ether2 active already? Or is it missing because you didn’t crop the whole of table?
Similarly for VID=1 and ports ether3, ether4 and ether5 …

They are added dynamically only when the port is active.
I’ve connected now devices on ether2 and ether3 and they show up exactly as you expected:
bridge_vlans.png