Manual:Bridge VLAN Table
Since RouterOS v6.41 it is possible to use a bridge to filter out VLANs in your network. To achieve this, you should use the Bridge VLAN Filtering feature. This feature should be used instead of many known bad VLAN configurations that are most likely causing you either performance issues or connectivity issues, you can read about one of the most popular misconfiguration in the VLAN in a bridge with a physical interface section. The most important part of the bridge VLAN filtering feature is the bridge VLAN table, which specifies which VLANs are allowed on each port, but configuring it might get quite complex if you are trying to set up a more advanced setup, for generic setups you should be able to configure your device using the Trunk and Access ports example, but the purpose of this guide is to in-depth explain and point out some of behaviour characteristics when using bridge VLAN Filtering.
Before explaining bridge VLAN filtering in-depth, you should understand a few basic concepts that are involved in bridge VLAN filtering.
- Tagged/Untagged - Under
/interface bridge vlanyou can specify an entry that contains tagged and untagged ports. In general, tagged ports should be you trunk ports and untagged ports should be your access ports. By specifying a tagged port the bridge will always set a VLAN tag from packets that are being sent out through this port (egress). By specifying an untagged port the bridge will always remove the VLAN tag from egress packets.
- vlan-ids - Under
/interface bridge vlanyou can specify for an entry which VLANs are allowed on specific ports. The VLAN ID is checked on egress ports. If the packet contains a VLAN that does not exist in the bridge VLAN table for the egress port, then the packet is dropped before packet is sent out.
- PVID - The Port VLAN ID is used for access ports to tag all ingress traffic with a specific VLAN ID. An dynamic entry is added to the bridge VLAN table for all ports for the VLAN ID that matches the VLAN ID, the port is automatically added as an untagged port.
- Īngress filtering - By default VLANs that don't exist in the bridge VLAN table are dropped before they are sent out (egress), but you can drop the packet when it is received (ingress).
- Management access - The bridge is supposed to simply forward packets between bridge ports and it would seem to other devices that there is simply a wire between them. With bridge VLAN filtering you can limit which packets are allowed to access the device that has the bridge configured, the most common practice is to allow access to the device only by using a very specific VLAN ID, but there are other ways you can grant access to the device. Management access is a great way to add another layer of security when accessing the device through a bridge port, this type of access is sometimes called the management port and it is related to the CPU port of a bridge.
CPU port - The bridge itself is a port as well, this is can be called as the CPU port since this is the port that is used to communicate with the device's CPU. When using bridge VLAN filtering, the CPU port is mostly used to create management access. Settings related to the CPU port are under
frame-type - You can filter out packets whether they have a VLAN tag or not, this is useful to add an extra layer of security for your bridge ports.
EtherType - By default a VLAN aware bridge will filter VLANs by checking the C-TAG (0x8100), all other VLAN tags are considered as untagged packets (without a VLAN tag). The selected EtherType will be used for VLAN filtering.
VLAN Tunnelling - If the EtherType of the packet does not match with the EtherType configured for the bridge, then ingress packets are considered as untagged packets, this behaviour gives a possibility to encapsulate VLANs into another, different VLAN. This also gives a possibility to divert specific traffic through different devices in your network.
Tag stacking - If a packet has a VLAN tag that matches the EtherType, then the packet is considered as a tagged packet, but you can force another VLAN tag regardless of the packet's content. By setting
tag-stacking=yes on a bridge port, you will add another VLAN tag with the PVID value on top of any other tag for all ingress packets.
Trunk/Access port setup
Below you can find a very common diagram for a very type of setup that consists of a trunk port and multiple access ports:
This setup is very common since it gives the possibility to divide your network into multiple segments while using a single switch and maybe a single router, such a requirement is very common for companies that want to separate multiple departments. With VLANs you can use different DHCP Servers, which can give out an IP address from a different subnet based on the VLAN ID, which makes creating Firewall rules and QoS a lot easier.
In such a setup you would connect some very generic devices like Desktop PCs to ether2 and ether3, these can be considered as workstations and they generally only use untagged traffic (it is possible to force a VLAN tag for all traffic that is sent out a generic workstation, though it is not very common). To isolate some workstations from other workstations you must add a VLAN tag to all packets that enters ether2 or ether3, but to decide what VLAN ID should the packet get is to use a concept called Port based VLANs. In this concept packets get a VLAN tag with a VLAN ID based on the bridge port to which the device is connected. For example, in this setup the device on ether2 will get a VLAN tag with VLAN20 and the device on ether3 will get a VLAN tag with VLAN30, this concept is very scalable as long as you have enough bridge ports. This should give you the understanding that traffic between the bridge and devices behind ether2/ether3 is untagged (since there is no VLAN tag, hence the name).
When we have determined our untagged ports, we can now determine our tagged ports. Tagged ports are going to be the trunk ports (the port, that carries multiple VLANs) and usually this port is connected to a router or another switch/bridge, you can have multiple trunk ports as well. Tagged ports are always carrying packets with a VLAN tag (hence the name) and you must ALWAYS specify the tagged ports for each VLAN ID you want this port to forward. It is possible that a port is a tagged port for one VLAN ID and the same port is an untagged port for a different VLAN ID, but this is for a different type of setup (Hybrid port setup).
Special note must be added for the PVID property. This property should be used on access ports, but it can be used for trunk ports as well (in Hybrid port setup). By using the PVID property you are adding a new VLAN tag with a VLAN ID that is specified in the PVID to all UNTAGGED packets that are received on that specific bridge port. The PVID does not have any effect on tagged packets, this means that, for example, if a packet with a VLAN tag of VLAN40 is received on ether2'that has
PVID=20, then the VLAN tag is NOT changed and forwarding will depend on the entries from the bridge VLAN table.
To configure the trunk/access port setup, you need to first create a bridge:
/interface bridge add name=bridge1 protocol-mode=none
Add the bridge ports and specify PVID for each access port:
/interface bridge port add bridge=bridge1 interface=ether1 add bridge=bridge1 interface=ether2 pvid=20 add bridge=bridge1 interface=ether3 pvid=30
Add appropriate entries in the bridge VLAN table:
/interface bridge vlan add bridge=bridge1 tagged=ether1 untagged=ether2 vlan-ids=20 add bridge=bridge1 tagged=ether1 untagged=ether3 vlan-ids=30
You might think that you could simplify this entry with a single entry, similar to this:
/interface bridge vlan add bridge=bridge1 tagged=ether1 untagged=ether2,ether3 vlan-ids=20,30
Do NOT use multiple VLAN IDs on access ports. This unintentionally will allow both VLAN20 and VLAN30 on both ports. For example, broadcast/multicast VLAN99 traffic from ether1 will be forwarded to ether2 and ether3 without a VLAN tag. This is because the bridge VLAN table holds an entry to allow both VLANs and packets should be sent out without a VLAN tag (since they are specified as untagged ports for both VLANs).
It is not necessary to add a bridge port as an untagged port, because each bridge port is added as an untagged port dynamically with a VLAN ID that is specified in the PVID property. This is because of a feature that automatically will add an appropriate entry in the bridge VLAN table for convenience and performance reasons, this feature does have some caveats that you must be aware of. All ports that have the same PVID will be added to a single entry for the appropriate VLAN ID as untagged ports, but note that the CPU port also has a VLAN ID.
For testing purposes we are going to enable VLAN filtering, but note that it might make you loose access to the device since it does not have a management access configured yet (we will configure it later). It is always recommended to configure VLAN filtering while using a serial console, though you can also configure a device through a port, that is not added to a bridge. Make sure you are using a serial console or connected through a different port (that is not in a bridge) and enable VLAN filtering:
/interface bridge set bridge1 vlan-filtering=yes
If you have enabled VLAN filtering now and printed out the current VLAN table, you would see such a table:
[admin@MikroTik] > /interface bridge vlan print Flags: X - disabled, D - dynamic # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED 0 bridge1 20 ether1 ether2 1 bridge1 30 ether1 ether3 2 D bridge1 1 bridge1 ether1
There is a dynamic entry added for VLAN1 since
PVID=1 is set by default to all bridge ports and our trunk port (ether1) has this value set, but you should also notice that bridge1 interface (the CPU port) is also added dynamically. This is because of the feature described above, internally the bridge checks which port is going to be used to send the packet out, but if it sees that the port uses the same PVID value, then there is no reason to add the tag (since it is going to be removed right away). Because the default value for all bridge ports (and for the CPU port too for that matter) is
PVID=1, then the bridge assumes that both ports are access ports and can be added as untagged ports. Such an entry will grant access from the trunk port (ether1) to the device using untagged traffic, which might not be desired.
There is a simple way to prevent the bridge (CPU port) being added as an untagged port, you can simply set the PVID on the trunk port to be different than the bridge's PVID (or change the bridge's PVID), but there is another option, which is more intuitive and recommended. Since you are expecting that the trunk port is only supposed to receive tagged traffic (in this example, it should only receive VLAN20/VLAN30), but no untagged traffic, then you can use ingress-filtering along with frame-type to filter out unwanted packets, but in order to fully understand the behaviour of ingress filtering, we must first understand the details of management access.
Management access is used to create a way to access a device through a bridge that has VLAN filtering enabled. You could simply allow untagged access and to do so it is fairly simple. Lets say you wanted the workstation behind ether3 to be able to access the device, we assumed before that the workstation is a generic computer that will not use tagged packets and therefore will only send out untagged packets, this means that we should add the CPU port (bridge1) as an untagged interface to the bridge VLAN table, to do so, simply specify the bridge1 and ether3 as untagged ports, but you should set these untagged ports for the VLAN entry that matches the PVID on the port, from which you will be connecting. In this case, you are going to connect from ether3 that has
PVID=30, so you change the untagged ports for VLAN30:
/interface bridge vlan set [find vlan-ids=30] untagged=bridge1,ether3
Allow access to the device using untagged traffic is not considered as a good security practice, a much better way is to allow access to the device using a very specific VLAN sometimes called the management VLAN, in our case this is going to be VLAN99. This adds a significant layer of security since an attacker must guess the VLAN ID that is being used for management purposes and then guess the login credentials, on top of this you even add another layer of security by allowing access to the device using only certain IP addresses. In order to allow access to the device using VLAN99 from ether3, we must add a proper entry in the bridge VLAN table:
/interface bridge vlan add bridge=bridge1 tagged=bridge1,ether3 vlan-ids=99
But you might notice that access using VLAN99 does not work at this point, this is because you need a VLAN interface that listens for tagged traffic, you can simply create this interface for the appropriate VLAN ID and you can set an IP address for the interface as well:
/interface vlan add interface=bridge1 name=VLAN99 vlan-id=99 /ip address add address=192.168.99.2/24 interface=VLAN99
At this point we can benefit from using ingress-filtering and frame-type. First we are going to focus on frame-type, which limits the allowed packet types (tagged, untagged, both), but in order for frame-type to work properly, ingress-filtering must be enabled, otherwise it will not have any effect. In our example, where we wanted to allow access from ether3 using tagged traffic (VLAN99) and at the same time allow a generic workstation to access the network, we can conclude that this port needs to allow tagged and untagged packets, but ether1 and ether2 is supposed to receive only specific types of packets, for this reasons we can enhance our network's security. Since ether1 is our trunk port, it is only supposed to carry tagged packets, but ether2 is our access port so it should not carry any tagged packets, based on these conclusions we can drop invalid packets:
/interface bridge port set [find where interface=ether1] ingress-filtering=yes frame-types=admit-only-vlan-tagged set [find where interface=ether2] ingress-filtering=yes frame-types=admit-only-untagged-and-priority-tagged
Lets say that you forgot to enable ingress-filtering and change the frame-type property on ether1, this would unintentionally add access to the device through ether1 using untagged traffic since PVID matches for bridge1 and ether1, but you are expecting only tagged traffic to be able to access the device. It is possible to drop all untagged packets that are destined to the CPU port:
/interface bridge set bridge1 frame-types=admit-only-vlan-tagged ingress-filtering=yes
This does not only drop untagged packets, but this disables the feature that dynamically adds untagged ports to the bridge VLAN table. If you print out the current bridge VLAN table you would notice that bridge1 is not dynamically added as an untagged port:
[admin@MikroTik] > /interface bridge vlan print Flags: X - disabled, D - dynamic # BRIDGE VLAN-IDS CURRENT-TAGGED CURRENT-UNTAGGED 0 bridge1 20 ether1 1 bridge1 30 ether1 ether3 2 D bridge1 1 ether1 3 bridge1 99 bridge1 ether3
While frame-type can be used to drop a certain type of packet, the ingress-filtering can be used to filter out packets before they can be sent out. To fully understand the need for ingress filtering, consider the following scenario: VLAN99 is allowed on ether3 and bridge1, but you can still send VLAN99 traffic from ether1 to ether3, this is because the bridge VLAN table checks if a port is allowed to carry a certain VLAN only on egress ports. In our case, ether3 is allowed to carry VLAN99 and for this reason it is forwarded. To prevent this you MUST use ingress-filtering. With ingress filtering, ingress packets are also checked, in our case the bridge VLAN table does not contain an entry that VLAN99 is allowed on ether1 and therefore will be dropped immediately. Of course, in our scenario without ingress filtering connection cannot be established since VLAN99 can be forwarded from ether1->ether3, but not from ether3->ether1, though there are still possible attacks that can be used in such a miscofiguration (for example, ARP poisoning).
The ingress-filtering can be used on the CPU port (bridge) as well, this can be used to prevent some possible attack vectors and limit the allowed VLANs that can access the CPU. It is better to drop a packet on an ingress port, rather than on an egress port, this reduces the CPU load, this is quite crucial when you are using hardware offloading with bridge VLAN filtering.
Even though you can limit the allowed VLANs and packet types on a port, it is never a good security practice to allow access to a device through access ports since an attacker could sniff packets and extract the management VLAN's ID, you should only allow access to the device from the trunk port (ether1) since trunk ports usually have better physical security, you should remove the previous entry and allow access to the device through the port that is connected to your router:
/interface bridge vlan add bridge=bridge1 tagged=bridge1,ether1 vlan-ids=99