How to remove 802.1Q header on "untagged" bridge egress

I have a bridge with some “untagged” ports. Some of my devices cannot understand this traffic, and sniffing the network I can see the problem. The “untagged” traffic still has a 802.1Q header with VLAN of 0. Now if the device was able to understand 802.1Q headers it will know that VLAN 0 is “no tag”, but it seems like the problem devices do not understand 802.1Q.

I have tested by setting vlan-filtering=no on the bridge and this does not send the header and the devices work, but then the whole bridge has no VLAN capability. I just want some bridge ports that have no 802.1Q header at all.

Is there some way to eliminate the 802.1Q header on egress with “untagged” traffic? There is no tagged traffic on the port, I don’t see why it needs any header.

To resolve this issue, I have create a Rube Goldberg solution. Routing the packets through a Linux server, I can remove the tag as follows:

tc qdisc del dev enp1s0f0np0v0 ingress
tc qdisc add dev enp1s0f0np0v0 handle ffff: ingress
tc filter add dev enp1s0f0np0v0 parent ffff: protocol 802.1q basic match 'meta(vlan eq 0)' action vlan pop

I might just move this device off of the Mikrotik bridge and onto a switch. The switch properly supports hybrid VLANs and does not add the 802.1Q header on untagged packets.

You’ll need to post your config. What you’re trying to do is possible and just comes down to assigning ports to a bridge VLAN as untagged if you configured VLANs properly via the bridge.

Concur, you should not have to do anything special for the router to work as desired.
Please post config
/export hide-sensitive file=anynameyouwish

Thanks guys.

Here is my config:

/interface bridge
add admin-mac=52:54:00:17:DE:AD auto-mac=no igmp-snooping=yes name=bridge1-lan vlan-filtering=yes
/interface bridge port
add bridge=bridge1-lan interface=ether3-plato
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether4
add bridge=bridge1-lan interface=ether2-shop
add bridge=bridge1-lan interface=ether1-switch
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether-vm-lan
/interface bridge vlan
add bridge=bridge1-lan comment=lan tagged=ether1-switch,ether2-shop vlan-ids=1
add bridge=bridge1-lan comment=wanonly tagged=bridge1-lan,ether1-switch,ether2-shop vlan-ids=2
add bridge=bridge1-lan comment=lanonly tagged=bridge1-lan,ether1-switch,ether2-shop vlan-ids=3
add bridge=bridge1-lan comment=privvpn tagged=bridge1-lan,ether3-plato vlan-ids=44

The resulting tagged/untagged:

/interface bridge vlan print detail

Flags: X - disabled, D - dynamic 
 0   ;;; lan
     bridge=bridge1-lan vlan-ids=1 tagged=ether1-switch,ether2-shop untagged="" current-tagged=ether1-switch,ether2-shop 
     current-untagged=bridge1-lan,ether-vm-lan,ether4,ether3-plato 

 1   ;;; wanonly
     bridge=bridge1-lan vlan-ids=2 tagged=bridge1-lan,ether1-switch,ether2-shop untagged="" current-tagged=bridge1-lan,ether1-switch,ether2-shop 
     current-untagged="" 

 2   ;;; lanonly
     bridge=bridge1-lan vlan-ids=3 tagged=bridge1-lan,ether1-switch,ether2-shop untagged="" current-tagged=bridge1-lan,ether1-switch,ether2-shop 
     current-untagged="" 

 3   ;;; privvpn
     bridge=bridge1-lan vlan-ids=44 tagged=bridge1-lan,ether3-plato untagged="" current-tagged=bridge1-lan,ether3-plato current-untagged=""

And here is a tcpdump of a random packet from the bridge on ether3-plato (see bridge1-lan MAC above). You can see the 802.1Q header with VLAN ID 0. I want to eliminate this header for all untagged packets.

listening on enp1s0f0np0v0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:27:11.326296 52:54:00:17:de:ad (oui Unknown) > 52:54:00:e4:94:5e (oui Unknown), ethertype 802.1Q (0x8100), length 114: vlan 0, p 0, ethertype IPv6, propjet.latt.net.ntp > 2001:470:redacted.42543: NTPv4, Server, length 48

If I force untagged (which I shouldn’t have to) like so, it still has the same problem:

/interface bridge vlan
add bridge=bridge1-lan comment=lan tagged=ether1-switch,ether2-shop untagged=ether3-plato vlan-ids=1

I would have to see the whole config to make any assessments and to be able to provide useful advice, but my only comment so far is do not use vlan1.
It is the default vlan and should be left as such. Change vlan1 to vlan10 for example
Additionally you are missing the bridge vlan rules that identify the untagging interfaces on the specific vlanids…

You have run into the same problem that we are facing with MT and bridging to speak to AT&T fiber in the US. See this thread for more details http://forum.mikrotik.com/t/bypassing-at-t-residential-gateways-with-mikrotik/135563/1 I have raised the issue with support already, but no resolution as of yet. It would probably help if more users report the problem.

Thanks! Yes, this looks like my same problem. Even the Wiki is wrong:
https://wiki.mikrotik.com/wiki/Manual:Bridge_VLAN_Table

By specifying an untagged port the bridge will always remove the VLAN tag from egress packets.

The “fix” is simple in concept. On “untagged” packets don’t add the 802.1Q header. This would be a software change for MikroTik.

@rpress Great! Would you be so kind and contact MT support and raise a bug too?

It may be the same problem but you have yet to provide the entire config and you are MISSING the UNTAG rules required in the bridge vlan rules.

I stated that in my previous message:


And I also showed that the rules were automatically added (as the Wiki explains):


According to my experience the /interface bridge port section in your config is lacking pvid settings on access (read: untagged) ports. Your config doesn’t say anything about “ether3-plato” being untagged member of VLAN 1 … yes, implicit (default) setup shows it as untagged member of VLAN 1, but using implicit setup can lead to unpredictable results. Apart from @anav’s suggeston to stay away from VLAN 1 (because it’s default for many things and you want to set up stuff explicitly) you really should set PVID on access ports for proper operations.

Thank you Sir MKX!! 3x genuflects!
Exactly and was why I was not able to state which interfaces were clearly untagged in the bridge vlan settings part, as it was not clear for which vlan-ids!!

So in these two lines add the missing info and then complete the bridge vlan rules for untagged interfaces
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether4 PVID=???
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether-vm-lan PVID=???

@anav It seems that you don’t know “export” does not show the default values? Even if I set “pvid=1” it still does not show in “export”. But you can see with “print detail” it is already set. I guess you can’t fathom that there is some problem with the bridge? Maybe because you have not seen it with your own eyes?

@mkx I have already shown twice that I had explicitly added the “untagged=ether3-plato” and it didn’t fix the problem… I indeed DO want to keep it as VLAN ID 1, because it is the default. On my Dell N1124P switch, it uses VLAN ID 1 as the “untagged” VLAN. This is already exactly what I want. The trunk ports from the Dell to the Mikrotik have the VLANs and then by default VLAN ID 1 is used for untagged access on the Dell.

I know you guys just want to help. But please it feels like you have “decided” what my problem is already, and aren’t actually reading what I am saying. And there was no explanation for my VLAN ID 0 in tcpdump. If indeed packets were leaving as tagged, then they would NOT be VLAN ID 0, they would be ID 1 or whatever else.

As shown in the other thread, it seems to be a bug.


Please look at this closely. You can see if I set pvid=2 it is shown in export, but pvid=1 is not.

[admin@VirtualRouter] > /interface bridge port set [find interface="ether4"] pvid=2

[admin@VirtualRouter] > /interface bridge port export      
# sep/07/2020 13:12:20 by RouterOS 6.47.3
# software id = 
#
/interface bridge port
add bridge=bridge1-lan interface=ether3-plato
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether4 pvid=2
add bridge=bridge1-lan interface=ether2-shop
add bridge=bridge1-lan interface=ether1-switch
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether-vm-lan

[admin@VirtualRouter] > /interface bridge port set [find interface="ether4"] pvid=1

[admin@VirtualRouter] > /interface bridge port export      
# sep/07/2020 13:12:21 by RouterOS 6.47.3
# software id = 
#
/interface bridge port
add bridge=bridge1-lan interface=ether3-plato
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether4
add bridge=bridge1-lan interface=ether2-shop
add bridge=bridge1-lan interface=ether1-switch
add bridge=bridge1-lan frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes interface=ether-vm-lan

/interface bridge port print detail
Flags: X - disabled, I - inactive; D - dynamic; H - hw-offload 
 0     interface=ether3-plato bridge=bridge1-lan priority=0x80 path-cost=10 internal-path-cost=10 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=no unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

 1     interface=ether4 bridge=bridge1-lan priority=0x80 path-cost=10 internal-path-cost=10 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no 
       pvid=1 frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

 2     interface=ether2-shop bridge=bridge1-lan priority=0x80 path-cost=10 internal-path-cost=10 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=no unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

 3     interface=ether1-switch bridge=bridge1-lan priority=0x80 path-cost=10 internal-path-cost=10 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=no unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

 4     interface=ether-vm-lan bridge=bridge1-lan priority=0x80 path-cost=10 internal-path-cost=10 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-only-untagged-and-priority-tagged ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no 
       bpdu-guard=no trusted=no multicast-router=temporary-query fast-leave=no

The “fix” is simple in concept. On “untagged” packets don’t add the 802.1Q header. This would be a software change for MikroTik.

I suspect the tag is originating upstream from ROS. Inferring from the other thread, ROS isn’t adding the tag. Rather, it sees it and treats the packet like a standard untagged packet, which means It simply forwards it and doesn’t modify the header. Disabling VLAN filtering “works,” because it likely just causes ROS to remove all tagging from inbound packets. You might be able to test this by enabling the IP firewall for all VLAN traffic. If I’m not mistaken, that will cause all packets to be routed, which likely means a stripped header. They’ll be tagged again when they go back through the virtual interface on egress. Even if it works though, it probably wouldn’t be a viable solution, because you’d effectively have to write rules to achieve what VLANs inherently give you. Plus, it’ll load the CPU.

One potential option is to try setting the default PVID to something other than 1, and then assign all ports to that VLAN as untagged. The idea would be to force all inbound, untagged traffic into a VLAN while on the bridge, and then have it untagged on egress. The hope would be that ROS replaces the 0 PVID with whatever you set the default PVID to, since it treats VLAN 0 as untagged traffic. Note though, you set up ether1 and ether2 as VLAN 1 tagged. This wouldn’t work (if it works at all) if you truly need VLAN 1 tagged though it seems unconventional to tag VLAN 1.

That’s an interesting idea, thanks for your thoughts. I have connected a PC directly to ether4 and pinged the PC on ether3-plato. Showing tcpdump from either side shows that egress has no 802.1Q but ingress has the header with VLAN ID 0.


From the ether4 side (the side that initiated the ping)…

16:59:28.804262 00:23:54:8c:62:93 (oui Unknown) > 00:0f:53:36:7b:00 (oui Unknown), ethertype IPv4 (0x0800), length 98: archimedes > 192.168.22.10: ICMP echo request, id 332, seq 1, length 64
16:59:28.804638 00:0f:53:36:7b:00 (oui Unknown) > 00:23:54:8c:62:93 (oui Unknown), ethertype 802.1Q (0x8100), length 102: vlan 0, p 0, ethertype IPv4, 192.168.22.10 > archimedes: ICMP echo reply, id 332, seq 1, length 64

From the ether3-plato side…

16:59:28.802350 00:23:54:8c:62:93 (oui Unknown) > 00:0f:53:36:7b:00 (oui Unknown), ethertype 802.1Q (0x8100), length 102: vlan 0, p 0, ethertype IPv4, 192.168.22.130 > 192.168.22.10: ICMP echo request, id 332, seq 1, length 64
16:59:28.802368 00:0f:53:36:7b:00 (oui Unknown) > 00:23:54:8c:62:93 (oui Unknown), ethertype IPv4 (0x0800), length 98: 192.168.22.10 > 192.168.22.130: ICMP echo reply, id 332, seq 1, length 64

Another test, again ping from ether4 now to the router IP (which is located directly on the bridge bridge1-lan interface). This should be similar to your idea to route packets through the firewall, I think.


17:04:40.610361 00:23:54:8c:62:93 (oui Unknown) > 52:54:00:17:de:ad (oui Unknown), ethertype IPv4 (0x0800), length 98: archimedes > _gateway: ICMP echo request, id 334, seq 1, length 64
17:04:40.610804 52:54:00:17:de:ad (oui Unknown) > 00:23:54:8c:62:93 (oui Unknown), ethertype 802.1Q (0x8100), length 102: vlan 0, p 0, ethertype IPv4, _gateway > archimedes: ICMP echo reply, id 334, seq 1, length 64

So at least to me it seems like the bridge is adding the tag on egress, even though the ingress to the bridge has no tag. Let me know if you have any other ideas, thanks again.

Interesting. It does look that way from those captures. If ROS is adding that tag, it may be something specific to your setup or the scenario, and it’s different from the issue described in the other thread if I read that one properly. I’m confident that ROS doesn’t assign VLAN 0 for all untagged packets. I have one port on my device that’s assigned as an untagged member of a VLAN, and the outbound packets are truly untagged regardless of whether the port is set up as an access or hybrid port. However, that’s not passing packets through as untagged ingress to egress as you’re doing. I’ll see if I can try that later if I have time. Unfortunately, I just have the one router, and it’s a 750 with only 5 ports, all of which feed different parts of the house i.e., I don’t have a test bench, so trying things out requires a bit of “creativity.”

In the meantime, did you try assigning a PVID (e.g., 1000) to ether3 and ether4 in the bridge port config and then assigning ether3 and ether4 as untagged members of that bridge VLAN (plus any other necessary changes like creating the virtual VLAN interface)? That would effectively turn ether3 and ether4 into access ports for a VLAN that only exists in the router. I’d expect that to work, since it’s not all that dissimilar from what I have working. If it does work, it may not necessarily give you a fix, but it’d at least narrow down the potential problem scenario(s).

All switches have vlan1 as default and the setup I described works.
I have an MT router connected to a Dlink managed switch connected to an MT capac
The same managed switch is connected to an MT switch
The same managed switch is connected to a managed netgear switch.

All with vlan 1 as default.
Note with bridge vlan filtering the default vlan-id is 1 and this is kept in the setup.
However one does not use vlan1 for anything, its just there and everything works just fine.
So its based on my usage not fairy tales.

http://forum.mikrotik.com/t/using-routeros-to-vlan-your-network/126489/1

Read use it , or continue on your merry way…

Just to clarify:

It really doesn’t matter what VLAN ID is used as default VLAN ID for untagged-only traffic as it’s used only internally to unit (be it mikrotik or any other managed switch). Which means that traffic on ethernet cable between MT and switch doesn’t (or at least should not) have VLAN tags if traffic belongs to “default” VLAN. Unless that VLAN is configured as tagged on a port. So you could have default VLAN set to 1000 on one device and default VLAN set to 1 on the other device and they would still happily exchange (untagged) frames on their interconnect.

Which brings us back to suggestion to not use VLAN ID 1 on ROS configs because it’s used in many places by default and makes hard to debug config … And my personal suggestion: when starting to use VLANs, never use untagged traffic (read: default VLAN) on LAN devices interconnections. Only use untagged on access ports.

When explained so succinctly even the blind, will be claiming they “see the light”!
Grab a coffee,
https://www.youtube.com/watch?v=gwgOUzodS6E
All night long!