IPv6 RA Incorrectly Advertising Prefixes from Other Interfaces (v7.18.2, Bridge+VLAN+PD)

Hi everyone,

I’m encountering a strange issue with IPv6 Router Advertisements on my MikroTik RB5009UPr+S+ running RouterOS v7.18.2 and hoping for some insights on whether this might be a bug or a subtle misconfiguration I’m missing. I’ve hidden my IPv6 prefix with YOUR_DELEGATED_PREFIX_BASE for privacy reasons. Also, excuse the formatting. I’m used to markdown.


Setup Overview:

  • ISP Router: Fritz!Box (rt1) providing internet access and a delegated IPv6 prefix via DHCPv6-PD (e.g., [YOUR_DELEGATED_PREFIX_BASE]::/60).
  • MikroTik Router (rt2): RB5009UPr+S+ (ROS v7.18.2). Connected to the Fritz!Box via a bridge interface (bridge). Acts as the internal router/switch.
  • Configuration:
  • rt2 obtains a prefix from rt1 using /ipv6 dhcp-client on the bridge interface (request=prefix pool-name=fritz!box).
    • rt2 has a bridge (bridge) with vlan-filtering=yes.
    • Several VLAN interfaces are configured on the bridge for different segments (e.g., vlan11 for k8s control plane, vlan12 for data, vlan13 for network).
    • A separate wireguard interface exists.
    • Specific /64 subnets from the delegated prefix are assigned to each VLAN interface and the WireGuard interface using /ipv6 address (e.g., [YOUR_DELEGATED_PREFIX_BASE]:fc::/64 for vlan11, ...:fd::/64 for vlan12, etc.).
    • /ipv6 nd prefix is configured (dynamically, D flag) to advertise the correct /64 prefix on its corresponding interface.
    • /ipv6 nd interface settings for vlan11, vlan12, vlan13 have ra-lifetime=none set to prevent rt2 from being a default router on these segments.
  • Clients: Talos Linux nodes connected to rt2 via trunk ports carrying the necessary VLANs (e.g., VLAN 11, VLAN 12). These nodes use SLAAC to configure IPv6 addresses based on received RAs.

The Problem:

Clients (Talos nodes) are incorrectly configuring multiple global IPv6 addresses via SLAAC on their VLAN sub-interfaces. Specifically:

  • The interface for VLAN 11 (end0.11) gets an address from its correct prefix ([YOUR_DELEGATED_PREFIX_BASE]:fc::/64) AND an address from the WireGuard prefix ([YOUR_DELEGATED_PREFIX_BASE]:ff::/64).
  • The interface for VLAN 12 (end0.12) gets an address from its correct prefix ([YOUR_DELEGATED_PREFIX_BASE]:fd::/64) AND an address from the VLAN 11 prefix ([YOUR_DELEGATED_PREFIX_BASE]:fc::/64).

This results in duplicate on-link routes on the clients for the incorrectly assigned prefixes.


Evidence:


1. MikroTik Configuration (Looks Correct):


  • /ipv6 address print detail shows each prefix (:fc:, :fd:, :fe:, :ff:) assigned correctly and uniquely to vlan11, vlan12, vlan13, wireguard respectively, with advertise=yes.
  • /ipv6 nd prefix print detail shows each prefix listed correctly for advertisement only on its intended interface.
  • /ipv6 nd print detail (interface settings) shows ra-lifetime=none correctly set on VLANs.

MikroTik rt2 (ROS 7.18.2) Config Snippets:

# /ipv6 address print detail (Global Addresses Only)
Flags: G - global
 0 G address=[YOUR_DELEGATED_PREFIX_BASE]:fd::1/64 interface=vlan12 advertise=yes
 1 G address=[YOUR_DELEGATED_PREFIX_BASE]:fe::1/64 interface=vlan13 advertise=yes
 2 G address=[YOUR_DELEGATED_PREFIX_BASE]:ff::1/64 interface=wireguard advertise=yes
 9 G address=[YOUR_DELEGATED_PREFIX_BASE]:fc::1/64 interface=vlan11 advertise=yes

# /ipv6 nd prefix print detail
Flags: D - dynamic
 0 D prefix=[YOUR_DELEGATED_PREFIX_BASE]:fc::/64 interface=vlan11 on-link=yes autonomous=yes ...
 1 D prefix=[YOUR_DELEGATED_PREFIX_BASE]:fd::/64 interface=vlan12 on-link=yes autonomous=yes ...
 2 D prefix=[YOUR_DELEGATED_PREFIX_BASE]:fe::/64 interface=vlan13 on-link=yes autonomous=yes ...
 3 D prefix=[YOUR_DELEGATED_PREFIX_BASE]:ff::/64 interface=wireguard on-link=yes autonomous=yes ...

# /ipv6 nd print detail (Interface Settings Only)
Flags: * - default
 0 * interface=all ra-lifetime=30m ... advertise-dns=yes ...
 1   interface=vlan11 ra-lifetime=none advertise-dns=yes ...
 2   interface=vlan12 ra-lifetime=none advertise-dns=yes ...
 3   interface=vlan13 ra-lifetime=none advertise-dns=yes ...

# /interface bridge print detail where name=bridge
Flags: X - disabled, R - running
 0 R name="bridge" mtu=auto actual-mtu=1500 l2mtu=10218 ... admin-mac=[RT2_MAC_ADDRESS] ... vlan-filtering=yes ... pvid=10 ... protocol-mode=mstp ...

# /interface vlan print detail where interface=bridge (Excerpt)
Flags: X - disabled, R - running; S - slave
 ...
   name="vlan11" mtu=1500 l2mtu=10214 mac-address=[RT2_MAC_ADDRESS] arp=enabled vlan-id=11 interface=bridge ...
   name="vlan12" mtu=1500 l2mtu=10214 mac-address=[RT2_MAC_ADDRESS] arp=enabled vlan-id=12 interface=bridge ...
   name="vlan13" mtu=1500 l2mtu=10214 mac-address=[RT2_MAC_ADDRESS] arp=enabled vlan-id=13 interface=bridge ...

# /ipv6 dhcp-client print detail
Flags: D - dynamic, X - disabled, I - invalid
 0 D interface=bridge pool-name="fritz!box" prefix-hint=::/60 request=prefix use-peer-dns=yes pool-prefix-length=64 dhcp-options=hostname,clientid add-default-route=yes use-interface-duid=no client-duid="...." status=bound

2. Client State (Incorrect):
Talos Client (talos-lhi-31e) Output Snippets:

# ip -brief -6 a l up (Excerpt)
end0.11@end0   UP     [YOUR_DELEGATED_PREFIX_BASE]:ff:[EUI64_INTERFACE_ID]/64 [YOUR_DELEGATED_PREFIX_BASE]:fc:[EUI64_INTERFACE_ID]/64 fe80::[EUI64_INTERFACE_ID]/64
end0.12@end0   UP     [YOUR_DELEGATED_PREFIX_BASE]:fc:[EUI64_INTERFACE_ID]/64 [YOUR_DELEGATED_PREFIX_BASE]:fd:[EUI64_INTERFACE_ID]/64 fe80::[EUI64_INTERFACE_ID]/64

# ip -6 -brief route (Excerpt)
[YOUR_DELEGATED_PREFIX_BASE]:fc::/64 dev end0.12 proto kernel metric 256 expires ... pref medium
[YOUR_DELEGATED_PREFIX_BASE]:fc::/64 dev end0.11 proto kernel metric 256 expires ... pref medium
[YOUR_DELEGATED_PREFIX_BASE]:fd::/64 dev end0.12 proto kernel metric 256 expires ... pref medium
[YOUR_DELEGATED_PREFIX_BASE]:ff::/64 dev end0.11 proto kernel metric 256 expires ... pref medium

3. Packet Capture (tcpdump on Client - The Proof):
Running tcpdump -i end0.11 -n 'icmp6 and ip6[40] == 134' -vv on the Talos node clearly shows Router Advertisement packets originating from rt2 (source fe80::[RT2_LINK_LOCAL_SUFFIX]) that contain TWO prefix info option entries: one for the correct :fc::/64 and one for the incorrect :ff::/64. This proves rt2 is sending incorrectly formed RA packets, despite its configuration appearing correct.


tcpdump on Talos end0.11 (Excerpt showing relevant RA):

# tcpdump -i end0.11 -n 'icmp6 and ip6[40] == 134' -vv
... IP6 (...) fe80::[RT2_LINK_LOCAL_SUFFIX] > ff02::1: ... ICMP6, router advertisement ...
        source link-address option (1), length 8 (1): [RT2_MAC_ADDRESS]
        rdnss option (25), length 40 (5):  lifetime ...s, addr: [YOUR_DELEGATED_PREFIX_BASE]:1:[FRITZBOX_INTERFACE_ID] addr: [ULA_PREFIX]:0:[FRITZBOX_INTERFACE_ID]
        prefix info option (3), length 32 (4): [YOUR_DELEGATED_PREFIX_BASE]:fc::/64, Flags [onlink, auto], ... [b]# CORRECT for vlan11[/b]
        prefix info option (3), length 32 (4): [YOUR_DELEGATED_PREFIX_BASE]:ff::/64, Flags [onlink, auto], ... [b]# INCORRECT for vlan11 (belongs to wireguard)[/b]
...

Troubleshooting Steps Taken:

  • Confirmed basic IPv6 connectivity works fine (clients can ping external IPv6 hosts).
  • Verified /ipv6 address, /ipv6 nd prefix, and /ipv6 nd settings on rt2 multiple times – they appear logically correct.
  • Rebooted client nodes – the incorrect addresses/routes are re-learned via SLAAC from the faulty RAs.
  • Checked client (Talos) configuration – no relevant static IPv6 addresses configured. Issue stems from SLAAC.
  • Confirmed DAD is not relevant here (issue is multiple prefixes on one interface, not duplicate IPs).
  • Confirmed ra-lifetime=none works correctly for suppressing default routes from rt2.

Question:


Given that the MikroTik configuration (/ipv6 address, /ipv6 nd prefix) looks correct, but the actual RA packets being sent (verified by tcpdump) contain prefixes belonging to other interfaces, is this likely:

  • A bug in RouterOS 7.18.2’s RA daemon, possibly related to interaction between DHCPv6-PD, VLANs on bridges, and prefix advertising?
  • A subtle misconfiguration in my bridge, VLAN, or DHCPv6-PD setup that I’m overlooking, which could cause the RA daemon to bundle prefixes incorrectly?

Has anyone encountered similar behavior? Are there known issues or workarounds for RouterOS 7.18.x in this area?

Thanks in advance for any insights or suggestions!

Adding some further findings to this issue:

1. Issue Affects Multiple Client Types:
I initially observed this on my Talos Linux nodes, but I’ve confirmed the exact same behavior occurs on my Linux workstation (Fedora/toolbx). Virtual interfaces mapped to specific VLANs (e.g., one for VLAN 11/k8s, one for VLAN 13/ncp) are receiving RAs from rt2 that cause them to configure SLAAC addresses from incorrect prefixes, in addition to the correct ones.


Workstation (toolbx) IP Address Output Snippet (Showing similar issue):

# ip -brief -6 a l up (Excerpt of virtual interfaces mapped to VLANs)
ncp@enp...   UP     [YOUR_DELEGATED_PREFIX_BASE]:fe:[IFACE_ID_1]/64 [YOUR_DELEGATED_PREFIX_BASE]:fe:[IFACE_ID_2]/64 [YOUR_DELEGATED_PREFIX_BASE]:fd:[IFACE_ID_3]/64 ... # Incorrect :fd: prefix present (Should only be :fe:)
k8s@enp...   UP     [YOUR_DELEGATED_PREFIX_BASE]:fc:[IFACE_ID_4]/64 [YOUR_DELEGATED_PREFIX_BASE]:fc:[IFACE_ID_5]/64 [YOUR_DELEGATED_PREFIX_BASE]:ff:[IFACE_ID_6]/64 ... # Incorrect :ff: prefix present (Should only be :fc:)

2. Correlation with DHCPv6-PD:
I can pinpoint when this started: the problem began immediately after I enabled IPv6 Prefix Delegation via the DHCPv6 client on rt2 (receiving a prefix from my upstream Fritz!Box) and configured rt2 to advertise the resulting sub-prefixes downstream onto the VLANs using its IPv6 ND capabilities (specifically, assigning addresses like [YOUR_DELEGATED_PREFIX_BASE]:fc::1/64 to vlan11 with advertise=yes, etc.). Before enabling the DHCPv6-PD client and relying on these dynamic advertisements, this issue did not occur.


This correlation strongly suggests the problem is related to how RouterOS v7.18.2 handles the generation of Router Advertisements for dynamically acquired/delegated prefixes in my Bridge+VLAN setup. It reinforces my suspicion that this might be a bug rather than a simple configuration error on my part, especially since the explicit /ipv6 address and /ipv6 nd prefix configurations appear correct.

Hoping this additional information helps narrow down the possibilities. Thanks!

I cannot confirm this problem.
When I started reading I thought “ah, he has Windows clients on a trunk interface”. But that is not what you report.
I have a similar setup somewhere (RB5009 behind Fritzbox, several VLANs with IPv6 from pool obtained from Fritzbox) and I do not observe the issue.
The RB5009 is running 7.18.1 but that likely is not different.
There is one thing “wrong” about your config: you should not put your Fritzbox port in the bridge, it should be a separate port (e.g. ether1) with all the other ports being in the bridge.

Interesting, you have a similar setup, but just not the same software versions? I use a Fritzbox 5530 by the way, with “Assign DNS server and IPv6 prefix (IA_PD)” enabled. It did delegate a prefix, but the Fritzbox displayed the prefixes a bit inconsistent. Meaning, sometimes it showed a /60, sometimes /64 for the prefixes I use on my rt2 (Routerboard). I disabled “Assign DNS server and IPv6 prefix (IA_PD)”, it only sends out DNS info over DHCP now.

Can you maybe share some snippets of how you configured your prefix delegation on the Fritzbox and your Routerboard?

I’ve done some more troubleshooting. For now I can only get things to work by using static routes on my Fritzbox and some other tweaks on the mikrotik side. With one odd thing, when I disabled forwarding for IPv6 on my Mikrotik Cloud Switch, it was still sending out RA’s to my rt2 to become a gateway. I had to set ra-lifetime to none for that VLAN interface on the switch. That’s a bit odd, right? Shouldn’t RA’s be disabled when it’s configured to not be a router?


Initial Problem: Multiple/Incorrect IPv6 Prefixes via RA / SLAAC

  • Symptom: Clients (Talos Linux nodes, Linux workstation) on VLANs behind my MikroTik router (rt2, ROS v7.18.2) were getting multiple global IPv6 addresses via SLAAC. For example, the interface on VLAN 11 (:fc::/64 network) was getting IPs from both :fc::/64 (correct) and :ff::/64 (incorrect, belongs to WireGuard). Similarly, VLAN 12 (:fd::/64) was getting IPs from :fd::/64 (correct) and :fc::/64 (incorrect).
  • Cause Diagnosis: Packet captures (tcpdump) on the clients confirmed that rt2 itself was sending malformed Router Advertisements (RAs). RAs sent on a specific VLAN interface contained prefix information options for BOTH the correct prefix AND incorrect prefixes belonging to other interfaces on rt2.
  • Trigger: This behavior started immediately after enabling DHCPv6 Prefix Delegation (receiving a prefix from rt1/Fritz!Box) on rt2 and attempting to use dynamic addressing/advertisement (from-pool or similar) for the downstream interfaces.
  • Resolution: I reconfigured rt2 to use static IPv6 addresses (e.g., [YOUR_DELEGATED_PREFIX_BASE]:fc::1/64 on vlan11) and static ND prefix advertisements (/ipv6 nd prefix entries without the D flag) for all its internal VLANs and WireGuard interface, ensuring each interface only advertises its own specific /64 prefix. This completely resolved the issue of clients getting multiple/incorrect IPs.
  • Conclusion: This strongly suggests a bug or instability in RouterOS 7.18.2’s handling of RA generation specifically when prefixes are derived dynamically from a DHCPv6-PD pool, potentially interacting with the bridge/VLAN setup. Using static configuration on rt2 bypassed this issue.

Second Problem: WireGuard IPv6 Connectivity / Incorrect Default Route

  • Symptom 1: After switching rt2 to static IPs and rebooting devices, WireGuard IPv6 connectivity failed. Diagnosis showed rt2 had NO default IPv6 route (::/0).
  • Cause 1: rt2’s /ipv6 settings had accept-router-advertisements=yes-if-forwarding-disabled. Since forward=yes was set (correctly, as rt2 is a router), this meant rt2 was ignoring RAs from rt1 (Fritz!Box).
  • Fix 1: Changed the setting on rt2 to accept-router-advertisements=yes.
  • Symptom 2: After Fix 1, rt2 learned the correct default route via rt1 on the bridge interface, BUT it also learned a second, unwanted default route via vlan13. This caused ECMP routing and firewall logs showed WireGuard traffic trying to exit via the wrong vlan13 gateway and being rejected.
  • Cause 2: Using /ipv6 neighbor print on rt2, we identified another device on VLAN 13 (MAC [SW1_MAC_ADDRESS], Link-Local fe80::[SW1_LINK_LOCAL_SUFFIX]) which was sending RAs advertising itself as a default router. This device was identified as sw1.
  • Fix 2: Reconfigured sw1 to stop advertising itself as a router (either by setting /ipv6 settings set forward=no or by setting /ipv6 nd ... ra-lifetime=none for the relevant interface/globally).
  • Result: rt2 now only has the single, correct default route via rt1 on the bridge interface.

Final Status:
With rt2 using static internal IPv6 configurations and sw1 correctly configured not to act as a router, the network is now stable:

  • Clients receive correct RAs and configure only the appropriate IPv6 addresses via SLAAC for their VLAN.
  • rt2 has the correct single default route to the internet via rt1.
  • WireGuard IPv6 connectivity is working as expected.
  • The strategy of receiving a dynamic delegation from rt1 via DHCPv6-PD (which allows rt1 to automatically route the prefix block to rt2) while using static internal assignments on rt2 (for predictability and avoiding the RA bug) is working well.

I’m now trying to backtrack what caused the issues. But somehow I cannot reproduce it anymore… I’m really interested in your setup and why you did not put your Fritzbox in the bridge. It probably has to do with your design/goal I guess?

Edit: I have the issue again. Trying to figure out what causes it…

I am using the RB5009 as a router, not as a bridge. So I do not put it in the bridge.
I have a DHCP client on ether1 with prefix request and pool, and addresses on all the VLAN’s “from pool”.
The rest works OK automatically.

I figured. My network design depends on VLANs for isolation. I only do some layer 3 management for those VLANs. My native VLAN is the same as the Fritzbox for easy management and exposing services to the internet.

Can you maybe share some snippets of your config? I wonder if I miss anything.

Rather than MT RA daemon broadcasting (well, multicasting) out of the wrong interfaces, I would be leaning more in the direction of a possible misconfiguration in your bridge VLAN filtering config that is causing traffic to leak between VLANs. But you didn’t include your whole config, so…

A drawing:
Screenshot From 2025-05-03 23-05-16.png
Sure, here’s my VLAN config.

[user@rt2] > /interface/bridge/vlan/print detail 
Flags: X - disabled, D - dynamic 
 0   ;;; public (native)
     bridge=bridge vlan-ids=10 tagged="" untagged=bridge,ether1,ether2,ether3,ether4,ether5,ether6,ether7,ether8 mvrp-forbidden="" current-tagged="" current-untagged=bridge,ether2,ether1,ether3,ether7,ether6,ether4,ether5 

 1   ;;; k8s control plane
     bridge=bridge vlan-ids=11 tagged=bridge,ether1,ether3,ether4,ether5,ether6,ether7,ether8 untagged="" mvrp-forbidden="" current-tagged=bridge,ether1,ether3,ether7,ether6,ether4,ether5 current-untagged="" 

 2   ;;; data control plane
     bridge=bridge vlan-ids=12 tagged=ether3,ether4,ether5,ether6,ether7,bridge untagged="" mvrp-forbidden="" current-tagged=bridge,ether3,ether7,ether6,ether4,ether5 current-untagged="" 

 3   ;;; network control plane
     bridge=bridge vlan-ids=13 tagged=bridge,ether1,ether8 untagged="" mvrp-forbidden="" current-tagged=bridge,ether1 current-untagged=""

My bridge ports

[user@rt2] > /interface/bridge/port/print detail 
Flags: X - disabled, I - inactive; D - dynamic; H - hw-offload 
 0   H ;;; rt1
       interface=ether2 bridge=bridge priority=0x80 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 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=yes mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 1   H ;;; rp1
       interface=ether3 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 2   H ;;; rp2
       interface=ether4 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 3   H ;;; rp3
       interface=ether5 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 4   H ;;; rp4
       interface=ether6 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 5   H ;;; rp5
       interface=ether7 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 6 I H ;;; glass
       interface=ether8 bridge=bridge priority=0x80 edge=yes point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=yes trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 7 X   ;;; sfp
       interface=sfp-sfpplus1 bridge=bridge priority=0x80 edge=auto point-to-point=auto learn=auto horizon=none auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no 

 8   H ;;; sw1
       interface=ether1 bridge=bridge priority=0x80 edge=auto point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no restricted-tcn=no pvid=10 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=yes 
       mvrp-registrar-state=normal mvrp-applicant-state=normal-participant multicast-router=temporary-query fast-leave=no

My IPv6 firewall

[user@rt2] > /ipv6/firewall/filter/print terse 
 0 D comment=special dummy rule to show fasttrack6 counters chain=forward action=passthrough
 1   comment=accept established,related,untracked chain=input action=accept connection-state=established,related,untracked
 2   comment=drop invalid chain=input action=drop connection-state=invalid
 3   comment=accept multicast chain=input action=accept dst-address-type=multicast limit=5,50:packet log=no log-prefix=
 4   comment=accept icmp chain=input action=accept protocol=icmpv6 limit=5,50:packet log=no log-prefix=
 5   comment=accept igmp chain=input action=accept protocol=igmp dst-address=ff02::/16 src-address-list=public in-interface=bridge log=no log-prefix=
 6   comment=accept udp traceroute chain=input action=accept protocol=udp dst-port=33434-33534 log=no log-prefix=
 7   comment=accept dhcpv6-client prefix delegation chain=input action=accept protocol=udp src-address=fe80::/10 dst-port=546 log=no log-prefix=
 8   comment=accept wireguard chain=input action=accept protocol=udp dst-address-list=public in-interface=bridge dst-port=13231 log=no log-prefix=
 9   comment=jump to network control plane rules (vlan13) chain=input action=jump jump-target=network control plane src-address-list=network control plane dst-address-list=network control plane in-interface=vlan13 limit=5,50:packet log=no log-prefix=
10   comment=jump to network control plane rules (wireguard) chain=input action=jump jump-target=network control plane src-address-list=wireguard dst-address-list=network control plane in-interface=wireguard limit=5,50:packet log=no log-prefix=
11   comment=accept localhost chain=input action=accept src-address=::1/128 dst-address=::1/128 in-interface=lo log=no log-prefix=
12   comment=reject input chain=input action=reject reject-with=icmp-admin-prohibited log=yes log-prefix=REJECT_INPUT
13   comment=fasttrack6 chain=forward action=fasttrack-connection connection-state=established,related log=no log-prefix=
14   comment=accept established,related, untracked chain=forward action=accept connection-state=established,related,untracked
15   comment=drop invalid chain=forward action=drop connection-state=invalid
16   comment=drop packets with bad src ipv6 chain=forward action=drop src-address-list=bad_ipv6
17   comment=drop packets with bad dst ipv6 chain=forward action=drop dst-address-list=bad_ipv6
18   comment=rfc4890 drop hop-limit=1 chain=forward action=drop protocol=icmpv6 hop-limit=equal:1
19   comment=accept icmp chain=forward action=accept protocol=icmpv6 dst-address-list=wireguard out-interface=wireguard limit=5,50:packet log=no log-prefix=
20   comment=accept wireguard to internet chain=forward action=accept src-address-list=wireguard in-interface=wireguard out-interface=bridge log=no log-prefix=
21   comment=jump to network control plane rules (wireguard) chain=forward action=jump jump-target=network control plane src-address-list=wireguard dst-address-list=network control plane in-interface=wireguard out-interface=vlan13 limit=5,50:packet log=yes log-prefix=
22   comment=reject forward chain=forward action=reject reject-with=icmp-admin-prohibited log=yes log-prefix=REJECT_FORWARD
23   comment=accept ssh chain=network control plane action=accept protocol=tcp dst-port=22,900 log=no log-prefix=
24   comment=allow winbox chain=network control plane action=accept protocol=tcp dst-port=8291 log=no log-prefix=

My bridge details

[user@rt2] > /interface/bridge/print detail 
Flags: D - dynamic; X - disabled, R - running 
 0  R ;;; defconf
      name="bridge" mtu=auto actual-mtu=1500 l2mtu=1514 arp=enabled arp-timeout=auto mac-address=xxx protocol-mode=mstp fast-forward=yes igmp-snooping=no auto-mac=no admin-mac=xxx ageing-time=5m priority=0x8000 max-message-age=20s forward-delay=15s transmit-hold-count=6 region-name="" region-revision=0 
      max-hops=20 vlan-filtering=yes ether-type=0x8100 pvid=10 frame-types=admit-all ingress-filtering=yes dhcp-snooping=no port-cost-mode=long mvrp=no max-learned-entries=auto

Hmm, that mostly looks correct. The other thing that gives me pause is that the ‘wireguard’ interface wouldn’t be a VLAN, and yet you said one of the VLANs on the client was SLAAC’ing from the ‘wireguard’ prefix. I also failed to notice until just now that you had previously written that the RAs you are packet-capturing on the client side actually contain two prefixes within a single RA packet…am I reading/understanding that right? You aren’t seeing two separate RA messages, but a single one advertising two prefixes within it?

If so, then the following suggestions/tests are likely a waste of time, but if not, I was going to suggest:

…setting ‘untagged=“”’ on your very first /interface/bridge/vlan entry. You don’t need to do that; just rely on the ‘pvid’ setting under /int/bridge/port to take care of that for you, which will cause that bridge port to be dynamically added to ‘current-untagged’ for that VLAN-ID. (Same for the bridge/CPU-facing switch port, when setting ‘pvid’ of the bridge itself under ‘/int/bridge/set pvid=’) In your case I highly doubt this is causing any issues; I am just inherently suspicious when I see anybody manually setting VLANs to ‘untagged’, since one wrong slip-up when manipulating that setting can quickly twist you up in knots.

…try to manually override the MAC addresses on the vlan interfaces on rt2, providing each one with a unique MAC. (Which should also cause rt2 to generate distinct fe80:: link-local suffixes per VLAN as well.) Then re-packet-capture the RAs on the client sides, and see if you are ever seeing RAs from the “wrong” MAC/link-local address showing up on a given VLAN. (If there is no VLAN leakage happening on rt2, and instead rt2 is in fact sending the wrong prefix(es) in the RAs it is transmitting out, then the source MAC will always be the correct one for that VLAN.) [EDIT: I forgot that ‘mac-address=’ is not an override-able VLAN interface parameter on ROS; however, you can work around this by creating one new bridge per VLAN, adding that VLAN interface as the sole member of that bridge, and changing the bridge’s MAC address. Also make sure to move any other config that previously referenced the VLAN interface directly – for example: IPv6 addresses, ND config – to instead refer to the new bridge interface.]

Are the RAs with the additional incorrect prefixes in them a unicast response to a RS emitted by the client(s), or are they within the regularly-transmitted unsolicited multicast ones? (Or both?) What do the router solicitations sent out by the clients look like…have you tried capturing those? What happens if you try to remove the client from one of the two VLANs it is on (like, actually turn down e.g. end0.11 on the client itself, but leave end0.12 up, not just removing that port from VLAN 11 on the rt2 bridge side)…does the behavior change?

If I understand correctly, your complaint is that RA received by a host on vlan11 contains an additional Prefix Information option (3) with prefix that does not belong to the current link.

Per RFC 4861:

A router SHOULD include all its on-link prefixes (except the link-local prefix) so that multihomed hosts have complete prefix information about on-link destinations for the links to which they attach.

However, it does seem wrong that, per tcpdump, the off-link prefix for wireguard is advertised as both on-link and for SLAAC.

Sounds like a strong case for a bug report.

I’ll try to reproduce the issue, but I can’t pinpoint what exactly the state was that caused this initial reported situation. By mistake I did have configured sw1 to obtain a prefix delegation from rt1, that Cloud Switch also had forwarding enabled for IPv4 and IPv6. That’s not needed, since it acts as a managed layer 2 switch. But as the tcpdump shows, the traffic came from rt2, not sw1. So I’m not sure how relevant it actually is. Maybe it also used RA to become a gateway or something like that. But then again, sw1 does not have the Wireguard network in its delegation. So that might have caused totally different issues (if at all). At the moment sw1 does not get a prefix and is not forwarding traffic anymore (as far as it did).

So, at the moment the IPs seem correct for my workstation and the Talos nodes. This situation is also stable, for now.

However, I did see this yesterday, but that too isn’t showing up anymore. Maybe it only happens when I reboot the nodes/network devices. I’ll test that.

2025-05-03 19:12:00 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:f47f]:55772->[WIREGUARD]:...3f]:6443, len 40                                                 
2025-05-03 19:12:05 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:51018->[WIREGUARD]:...33]:6443, len 40                                                                                                                                       
2025-05-03 19:13:15 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:f47f]:44950->[WIREGUARD]:...33]:6443, len 40                                                                                                                                       
2025-05-03 19:13:56 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:57040->[WIREGUARD]:...3f]:50001, len 40                                                                                                                                      
2025-05-03 19:13:56 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:57502->[WIREGUARD]:...33]:50001, len 40                                                                                                                                      
2025-05-03 19:13:56 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:57512->[WIREGUARD]:...33]:50001, len 40                                                                                                                                      
2025-05-03 19:13:56 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:57042->[WIREGUARD]:...3f]:50001, len 40                                                                                                                                      
2025-05-03 19:13:58 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:51118->[WIREGUARD]:...33]:50001, len 40                                                                                                                                      
2025-05-03 19:13:58 firewall,info REJECT_FORWARD forward: in:bridge(ether2) out:wireguard, connection-state:new src-mac ...:6c:88, proto TCP (SYN), [PUBLIC]:...:dd0d]:52914->[WIREGUARD]:...3f]:50001, len 40

What you’re seeing there is that the Talos nodes try communicate with each other for K8s and Talos control plane ports. This is expected. However, not over these networks. Talos is configured to use VLAN 11 for that. Also, the Talos nodes should not be aware of the Wireguard network. They also don’t have these addresses. For whatever reason they use the public prefix network (VLAN 10) to communicate with each other with dst address of the Wireguard network. The firewall is correct for dropping these connections. But they shouldn’t even happen. I checked at the time when these logs appeared and the Talos nodes did not have the Wireguard network. Which is even weirder for me.

I double checked the YAML files of the Talos nodes, they don’t have the Wireguard network configured. In fact, that config pre-dates the existence of that network. So I cannot even have configured it manually for those nodes.

I’ll see if I can have a look at this today as well. Any tips and advice is welcome.

My todo:

  • Try to reproduce the firewall logs with the Wireguard address first, by rebooting all devices (Mikrotik and Talos nodes).


  • Try to reproduce the situation where the nodes got the Wireguard address (maybe sw1 was involved somehow).

The only time when I saw multiple prefixes being announced is when there indeed were multiple prefixes on the interface.
At another site we have two ISP uplinks with IPv6 and I experimented with announcing both their prefixes on the local network.
That worked OK, but it did not look like the client devices made sensible use of it, so I discontinued that.
Also in old RouterOS versions there was the problem that when an address was withdrawn and another address assigned, it would continue to publish the old address. However that was fixed way before 7.18.2

But those were then prefixes from 2 different delegations? Because I didn’t see prefixes from the other Mikrotik. Only from rt2 itself, on interfaces that weren’t in the VLAN that should get those prefixes.

I haven’t been able to reproduce it so far. I rebooted all devices. Nothing. I’ll try later to setup sw1 again as it was, with forwarding enabled.

Interesting. Came across this issue. Updated my mikrotik and this went away. I was pulling my hair out trying to figure out why VMs were getting prefixes meant for other vlans. I think this was fixed in 7.20.1:

ipv6,ra - fixed prefix unlinking from interface on configuration change and stop deprecating prefixes when the validity lifetime expires;