Bridging VLAN and EoIP

Hello,

I’m working on a configuration where I have a bridge between an EoIP interface, and a VLAN interface. The VLAN interface is related to a master interface at which there is connected a UniFI antenna. The end goal is to have clients connected to the SSID of the UniFI to be tagged with the VLAN ID and to be bridged towards the EoIP interface (which provides its own DHCP server, etc.)

As of now the configuration works half way; indeed, I have a dedicated bridge where only the EoIP and VLAN interface are present. When a device connects to the UniFI, it receives an IP address that belongs to the pool of addresses at the other end of the EoIP. I can ping the outer internet and the devices on the EoIP LAN, however I can’t browse (nor internet, nor connect to devices on the EoIP LAN).

Anyone had similar issues?

If you can ping even public addresses through the EoIP tunnel, it sounds like an MTU issue (if you haven’t forced the MTU of the EoIP interfaces to 1500, which is what the wireless clients probably expect) or a reassembly issue (if you have forced the MTU of the EoIP interfaces to 1500, so the size of the EoIP packets exceeds the usually available MTU on the underlying path and thus they get fragmented on sending). What MTU do the EoIP interfaces and the bridges they are connected to show?

Hello,

so:

Mikrotik 1 (“local”):

EoIP has Actual MTU at 1500, L2 MTU at 65535

VLAN interface has Actual MTU 1500, L2MTU 1594

Bridge that contains both Actual MTU 1500, L2 MTU 1594

Mikrotik 2 (“remote”)

EoIP has Actual MTU at 1500, L2 MTU at 65535

Bridge that contains the EoIP Actual MTU 1500, L2 MTU 1598

If so, try attaching a DHCP client with add-default-route set to no to the bridge that joins the EoIP with the Ubnt-facing VLAN interface and try pinging the IP attached to the remote end of the EoIP tunnel with size=1500. Do you get responses?

As soon as I did that, the EoIP interface went from “RS” into “S” mode. I had to disable the DHCP Client to get it back up… weird

I can try to associate an address manually

Even if I add an address manually to the bridge, the interface goes from “RS” into “S” and I can’t ping the other end (by forcing the ping through the bridge itself)

Show me the configuration exports, that indeed sounds strange, unless the addresses are from the same subnet.

/interface bridge
add mtu=1500 name=Bridge_VLAN
add admin-mac=2C:C8:1B:28:D8:4D auto-mac=no comment=defconf name=bridge
/interface eoip
add local-address=192.168.178.2 mac-address=02:7A:DE:C9:60:13 mtu=1500 name=\
    eoip-tunnel1 remote-address=192.168.26.1 tunnel-id=501
/interface vlan
add interface=ether2 name=VLAN20 vlan-id=20
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add name=Site_A_interface
add name=Site_B_interface
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
add authentication-types=wpa2-psk mode=dynamic-keys name=Site_A \
    supplicant-identity=MikroTik
/interface wireless
set [ find default-name=wlan1 ] band=2ghz-b/g/n country=ireland disabled=no \
    distance=indoors frequency=2462 installation=indoor security-profile=Site_A \
    ssid=McRouter wireless-protocol=802.11
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
add name=dhcp_pool1 ranges=192.168.77.2-192.168.77.254
/ip dhcp-server
add address-pool=default-dhcp interface=bridge name=defconf
add address-pool=dhcp_pool1 disabled=yes interface=Bridge_VLAN name=dhcp1
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=pwr-line1
add bridge=Bridge_VLAN interface=VLAN20 pvid=20
add bridge=Bridge_VLAN interface=eoip-tunnel1
/ip neighbor discovery-settings
set discover-interface-list=Site_B_interface lldp-med-net-policy-vlan=1
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=wlan1 list=WAN
add interface=bridge list=Site_A_interface
add interface=ether1 list=Site_A_interface
add interface=ether2 list=Site_A_interface
add interface=ether3 list=Site_A_interface
add interface=ether4 list=Site_A_interface
add interface=eoip-tunnel1 list=Site_B_interface
add interface=*A list=Site_B_interface
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
    192.168.88.0
add address=192.168.77.1/24 interface=ether4 network=192.168.77.0
/ip dhcp-client
add comment=defconf interface=wlan1
add add-default-route=no disabled=yes interface=Bridge_VLAN use-peer-dns=no \
    use-peer-ntp=no
/ip dhcp-server network
add address=192.168.77.0/24 gateway=192.168.77.1
add address=192.168.88.0/24 comment=defconf dns-server=192.168.88.1 gateway=\
    192.168.88.1
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan
/ip firewall filter
add action=accept chain=input src-address=192.168.178.0/24
add action=accept chain=input dst-port=47 protocol=tcp
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related hw-offload=yes
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" \
    dst-port=33434-33534 protocol=udp
add action=accept chain=input comment=\
    "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\
    udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \
    protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=input comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
add action=accept chain=forward comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment=\
    "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \
    hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=\
    500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=forward comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
/system logging
add topics=interface
/system note
set show-at-login=no
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN
/tool sniffer
set file-name=capture881 filter-interface=VLAN20 memory-scroll=no

You have posted only the export from the “local” end, so some information is missing; however, what is definitely wrong is that the VLAN interface VLAN20 is hooked to ether2 whilst ether2 is a member port of bridge bridge. Such an arrangement is incorrect and known to cause issues, so you have to set the interface of VLAN20 to bridge.

What IP address did you assign to Bridge_VLAN that made the tunnel fail?

Thanks a lot for the reply. But adding VLAN20 to the bridge “bridge”, wouldn’t defeat the purpose of bridging VLAN20 packets onto EoIP?

IP: 192.168.26.11/24

It’s not adding the tagless end of VLAN20 as a member port of the bridge, it’s rooting the tagged end of VLAN20 in the bridge whose member port is ether2. So the frames tagged with VID 20 that ingress via ether2 will get to the tagged end of VLAN20 via bridge bridge and egress there, get untagged, ingress to bridge Bridge_VLAN, and egress via eoip-tunnel1.

I will try this asap and let you know.

Just for my curiosity: how would packets untagged in bridge get onto Bridge_VLAN ?
I am missing this part

Thanks

Got you, sorry.
Will test asap

They are not untagged by the bridge, they get from ether2 to the tagged end of the VLAN20 pipe still tagged. It’s the passage through VLAN20 that removes the tag. In the opposite direction, the tagless frame that arrives via eoip-tunnel1 passes through Bridge_VLAN to the tagless end of the VLAN20 pipe, gets tagged with VID 20 and emerges on bridge to get forwarder to ether2.

Thanks for the explanation.

I did the test, but still I can’t browse nor internet websites nor sites hosted on local machines on the remote end.

Interesting info: on the remote side there is a DNS server (PiHole). If I query it using dig, I get the reply back. If I try to open the web interface, it does not work

We have to go step by step. So far I still have no other idea than fragmentation issues (the EoIP transport packets carrying a 1514-byte Ethernet frame are far bigger than 1500 bytes, so they have to be fragmented in order to pass through paths with L3 MTU of 1500, and if something is miscofnigured in your firewalls or somewhere in the ISP network between the two devices talking EoIP, the non-first fragments may get dropped, causing the complete packet to be dropped as it cannot be reassembled at the receiving side).

So first thing I need to see is the export from the remote end and the address you attempted to attach to the Bridge_VLAN. The goal is to understand why the EoIP goes down as you add the address (I suspect it attempts to send the EoIP transport packets as EoIP payload), fix that, and move on to testing the passage of large ping packets through the tunnel, using ping remote.ip.add.ress size=1500 do-not-fragment.

Hello,

sorry for the late reply.

In the end I was able to get it working, after a full reset. I made some changes with respect to the previous try; one major aspect is that in this (working) configuration, the Mikrotik establishing the EoIP connection “lives” in the same subnet of the existing router that provides connectivity to the internet. In the previous config, the Mikrotik was set as a DHCP client (through WiFi bridge).

However, I still have few questions and doubts about the VLAN mechanisms in MikroTik.

I will attach here below the current (and working) configuration, but I wanted to start this post with some questions:

VLAN virtual interfaces

  • Does a virtual VLAN interface react only to packets tagged with the specific VLAN ID?


  • What happens when a properly tagged packet reaches a virtual VLAN interface? Does it get “untagged” by the interface, or does it preserve the 4bytes for VLAN identifier?


  • What happens when a virtual VLAN interface is bridged with another (non VLAN-ified) interface ? If we consider packets flowing from VLAN interface → “regular” port. Are the packets bridged? If yes, is the tag removed?


  • Still related to the above question: What happens if packets now need to travel from the “regular” port → VLAN virtual interface? Are the packets bridged? If yes, is the tag added?

Bridge VLAN filtering

  • What is the purpose of a Bridge-based VLAN filtering?


  • How does it complement / differentiate with respect to using the virtual VLAN interface?


  • When is better/suggested to use one approach over the other?

Thanks!

Configuration


/interface bridge
add admin-mac=2C:C8:1B:28:D8:4D auto-mac=no name=bridge_lan vlan-filtering=\
    yes
add mtu=1500 name=bridge_vlan_20
/interface wireless
set [ find default-name=wlan1 ] band=2ghz-b/g/n channel-width=20/40mhz-XX \
    distance=indoors frequency=auto installation=indoor mode=ap-bridge ssid=\
    MikroTik-28D851 wireless-protocol=802.11
/interface ethernet
set [ find default-name=ether1 ] name=LAN_1
set [ find default-name=ether2 ] name=LAN_2
set [ find default-name=ether3 ] name=LAN_3
set [ find default-name=ether4 ] name=LAN_4
/interface eoip
add local-address=192.168.178.2 mac-address=02:52:9E:44:93:E6 mtu=1500 name=\
    EoIP_Site_B remote-address=192.168.26.1 tunnel-id=501
/interface vlan
add interface=LAN_3 name=vlan_terminator_20 vlan-id=20
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
add name=dhcp_pool1 ranges=192.168.22.2-192.168.22.254
add name=dhcp_pool2 ranges=192.168.78.2-192.168.78.254
/ip dhcp-server
add address-pool=dhcp_pool2 disabled=yes interface=bridge_vlan_20 name=dhcp1
/interface bridge port
add bridge=bridge_lan comment=defconf interface=LAN_2
add bridge=bridge_lan comment=defconf interface=LAN_3
add bridge=bridge_lan comment=defconf interface=LAN_4
add bridge=bridge_lan comment=defconf interface=pwr-line1
add bridge=bridge_lan comment=defconf interface=wlan1
add bridge=bridge_vlan_20 interface=vlan_terminator_20
add bridge=bridge_vlan_20 interface=EoIP_Site_B
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface bridge vlan
add bridge=bridge_lan tagged=LAN_3 vlan-ids=20
/interface list member
add comment=defconf interface=bridge_lan list=LAN
add comment=defconf interface=LAN_1 list=WAN
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge_lan network=\
    192.168.88.0
add address=192.168.178.2/24 interface=bridge_lan network=192.168.178.0
add address=192.168.78.1/24 disabled=yes interface=bridge_vlan_20 network=\
    192.168.78.0
/ip dhcp-client
add comment=defconf interface=LAN_1
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf dns-server=192.168.88.1 gateway=\
    192.168.88.1
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related hw-offload=yes
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.178.1 \
    routing-table=main suppress-hw-offload=no
/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" \
    dst-port=33434-33534 protocol=udp
add action=accept chain=input comment=\
    "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\
    udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \
    protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=input comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
add action=accept chain=forward comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment=\
    "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \
    hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=\
    500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=forward comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
/system note
set show-at-login=no
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

A VLAN interface is nothing more than a “pipe” whose one end (“tagless”) acts as an L2 interface itself and the other one (“tagged”) is attached to another L2 interface. When “something” (typically, the IP stack) sends a frame through the “tagless” end of the VLAN interface, the pipe adds a VLAN tag to it and sends it via the underlying interface; if a “properly tagged” frame (i.e. one carrying the VID the “pipe” is set to handle) arrives to the underlying interface, the pipe takes it, removes the tag, and outputs it to the connected IP stack tagless. Other than that, the pipe is dumb - it does not care whether the frame carries an IP packet, and IPv6 packet, or maybe an STP BPDU, or even an already tagged frame on the “tagless” end. So you can indeed bridge the tagless ends of two VLAN interfaces together and create a “short circuit” between two (or more) VLANs that way, or you can stack multiple VLAN tags by connecting the tagged end of one “pipe” to the taggless end of another one. Setups like these are only useful in very specific cases but they are technically possible.


With vlan-filtering set to no, the bridge is VLAN-agnostic; it only works with MAC addresses and ignores any eventual VLAN tags. So if a frame comes tagged on ingress, it stays tagged on egress. Setting vlan-filtering to yes makes the bridge VLAN-aware, which means you can define each port as an access/tagless member of a particular VLAN (so that tagless frames get tagged on ingress and untagged on egress through that port) or as a trunk/tagged member of a VLAN (so that tagged frames stay tagged). A frame can only egress through a port if that port is an access or trunk member of the VLAN the frame is tagged with. With ingress-filtering set to yes on a port, the port will even not accept an ingress frame if the VID in its tag doesn’t match one of the VLANs the port is a member of.

Nowadays, the VLAN interfaces do not serve as a substitution of VLAN filtering on a bridge any more. Normally, you use vlan filtering on a single common bridge, and only if you need the router itself to have access into a given VLAN on the bridge, you must attach a VLAN interface to the bridge. Years ago, when VLAN filtering was not available, you had to attach a VLAN interface to each physical interface you wanted to make a trunk port of the VLAN and bridge the tagless ends of the VLAN interfaces together, so you ended up with a dedicated bridge for each VLAN, but this approach is not compatible with the “normal” switches because if you use such a setup, you end up with a “PVST-”, i.e. a separate spanning tree for each VLAN controlled using the standard RSTP protocol.

Thanks a lot for the explanation! This makes a LOT of sense to me, now!

So, following your comments, the use of the bridge VLAN filtering could allow the creation of 1 bridge only, and- through a combination of PVIDs and VLAN table entries - could achieve the same result as creating different bridges and VLAN interfaces. Is my statement (at high level) correct?

Thanks

If the intention is to get the same behavior like a single VLAN-aware hardware switch, then yes.