Bridge host entry stays on ethernet port after client roams to MikroTik radio (traffic black-holes until ageing-time)

Setup

hAP ac2 (RBD52G-5HacD2HnD), RouterOS 7.23.1 stable, switch chip Atheros-8327.
bridge1: ether2-5 (hw=true) plus wlan2.4 and wlan5G, protocol-mode=rstp, fast-forward=yes, ageing-time=5m (default).
A second, third-party AP (ISP router in AP/bridge mode) hangs off ether3 and broadcasts the same SSID on both bands, so clients roam between the two APs.

Symptom

When a client roams from the third-party AP to the MikroTik's own radio, the bridge keeps the client's MAC on the ethernet port:

/interface wireless registration-table -> MAC on wlan5G
/interface bridge host -> same MAC on ether3

Downstream traffic is therefore sent out ether3 and lost. The client is associated, has a bound DHCP lease, and is transmitting - but receives nothing. Registration-table byte counters sampled over 30 s:

tx (to client): 10672 -> 10688, +16 bytes
rx (from client): 102276 -> 104112, +1836 bytes

/ping from the router to the client: 100% loss. From another wired host on the same subnet: 100% loss as well.

It self-heals after about 5 minutes, matching ageing-time exactly:

11:48:08 - client re-associates to wlan5G (log: "connected, signal strength -56")
11:51-53 - bridge host still shows ether3, ping 100% loss
11:57:24 - entry gone from bridge host, ping 0% loss

Re-association alone does not fix it: the wrong entry survived a full disconnect/reconnect cycle.

What I already checked

The documented switch-chip caveat ("the switch-cpu port will always participate in the host learning process when at least one hardware offloaded bridge port is active on the switching group") applies to Atheros8316 / Atheros8227 / Atheros-7240 only. The Atheros-8327 on this board is not in that list, so I don't think that is the explanation here.

I have lowered ageing-time to 1m as a mitigation, which should cut the outage from about 5 minutes to about 1, but that only treats the symptom.

Questions

Why doesn't source-MAC learning on wlan5G move the FDB entry off ether3 on the first frame received from the client?

Is this expected when a foreign AP with the same SSID sits behind a hardware-offloaded port?

Is there a better fix than lowering ageing-time? Would hw=no on the port facing the second AP, or fast-forward=no, be the recommended workaround?

For context on why this matters: roaming happens 11-15 times a day per phone here, so in the worst case this adds up to nearly an hour a day of "connected but no internet" per device - which is exactly what makes people turn Wi-Fi off on their phone.

Thanks for any pointers.

If bridge is offloaded to hardware, it's most often only offloaded partially ... for traffic between offloaded bridge ports. Which means that there are two FDBs, one in switch chip and one in software stack. And each FDB is probably maintained separately by their own mechanizms. When station moves to "local radio" and communicates with "local IP stack" (e.g. DHCP service), switch chip doesn't see any of frames and hence can't update its FDB. If/When station communicates with anything connected to offloaded ports, then switch chip should be able to update its FDB.

But that really has to be station-initiated communication, otherwise switch won't see any frames with appropriate SRC MAC address entering via new switch/bridge port.

Or are you saying that it doesn't happen this way?

Thanks, that matches what I see - and I think I have a data point that supports it and adds a nasty corollary.

The client that black-holes is only talking to the router itself: DHCP renew, DNS, and internet via pppoe-out1. All CPU-side. So by your model the switch chip never sees a frame with that SRC MAC on a new port and keeps the stale ether3 entry. That fits, and it explains something that had puzzled me: the registration-table byte counters showed the client transmitting the whole time (+1836 bytes rx in 30 s while tx to the client was frozen at +16), so I expected learning to happen. It was transmitting, just never towards anything the switch chip can see.

The corollary is that it cannot recover on its own. I also pinged the phone from a wired host sitting on ether2, which is an offloaded port. That failed 100% as well. Under your model the echo request enters the switch chip, the chip still believes the MAC is behind ether3 and sends it out there, so the phone never receives it and never replies - and that reply is exactly the station-initiated frame that would have fixed the FDB. The one thing that would heal it is prevented by the stale entry itself. It clears on ageing and nothing else.

Since then I lowered ageing-time from 5m to 1m. Over the last 24 h a monitor caught 3 episodes, each measured at about 2 minutes with a 2-minute sampling interval, so consistent with roughly one ageing period. Much shorter, still there. I have just tightened the sampling to 1 minute to get the real figure.

Is hw=no on the port facing the second AP the right targeted fix? My reasoning is that with that port CPU-bridged the chip would never learn the client on ether3 in the first place, so there would be a single consistent FDB for that path, at the cost of CPU for that port's traffic. Or would you disable offload for the whole bridge?

hw=no on the bridge port connecting the external AP should fix this.

More generally, the client is supposed to send out GARP packets for this exact reason when it roams. Why doesn't it do so? Does it do so, but somehow they're mishandled? Is it only the single device that has this problem?

Sometimes having rstp enabled on the internal AP port causes things like this, especially if only the single device is connected. It would be a good idea to set disable-running-check=yes on the wifi interfaces to see if it helps.

Thanks - that answers my question, and I can answer some of yours.

It is not a single device. My monitor has logged 5 episodes so far across both phones, a Galaxy A34 and an A26, so it is not one client misbehaving.

On the running check: it was at the default, and there is a direct symptom on my box. Before changing anything, wlan5G reported running=false because no client happened to be associated, while wlan2.4 reported true. So the wireless bridge ports do go up and down as clients come and go, which is exactly the condition you describe. I have now set disable-running-check=yes on both radios and both report running=true steadily. I will report whether the episodes stop.

Data point in the meantime: after lowering ageing-time from 5m to 1m, and with my sampling tightened from 2 minutes to 1, the episodes now measure exactly 1.0 minute instead of the 2.0 I reported earlier - the earlier figure was an artefact of the sampling interval. So the outage tracks the ageing period precisely, which fits the two-FDB explanation: nothing clears it early, it simply expires.

The GARP question is a good one and I had not considered it. A gratuitous ARP is broadcast, so it should reach the switch chip and correct its FDB, which would make the whole thing self-healing. I have started a capture filtered on arp and the two phone MAC addresses, taken from a wired host on the LAN, and I will correlate it with the next episode my monitor flags. If the phones do send a GARP on roam then something is eating it, and if they do not, that is worth knowing too. I will post what comes out.

I am deliberately holding off on hw=no for now, so that if the episodes stop I know it was the running check and not the two changes together.

Just to serve curiosity: if you'll allow for station to "black hole" again, try to run a ping ftom station towards wired PC. That should IMO update switch chip's FDB. And that would IMO be the ultimate proof of my theory.

But anyways, as @lurker888 writes, if everything worked as it should, station should not become unaccessible from wired part of your network. I've had a few devices with AR8327 (RB951G) in similar scenario (although running ROS v6 at the time) but I've never encountered similar problem.

AR8327 inside RBD52G is not the same as hardware part with same identification though ... it's got a bug which gets into action when running PPPoE over tagged bridge with WAN-facing port set as access/hybrid port ... while "real" AR8327 doesn't have such a bug (I'm working around the bug by running RBD52G in a "router on a stick" manner with another switch doing the "access port" function). So I wouldn't dismiss the possibility of another bug.

Confirmed, with a deterministic reproduction and a matching user-visible symptom.

How to reproduce: park the client near the other AP until the bridge has learned its MAC on the ethernet port facing that AP, then move to the MikroTik while the client is actively using the network. That last part matters: an idle phone asks the network for nothing, so the fault stays invisible. That is why it went unnoticed for days.

Measurement. Client on wlan5G at -46 to -56 dBm, so no RF issue. The counter is ARP requests for the gateway sent by the client and never answered:

22:20:10 radio=wlan5G bridge=ether3 arp=72

22:20:56 radio=wlan5G bridge=ether3 arp=112 (+40 in 46 s)

22:21:11 radio=wlan5G bridge=- arp=116 <- entry expires, requests stop instantly

22:21:56 radio=wlan5G bridge=- arp=116

The requests stop in the exact second the stale entry expires. That is the causal link, not a correlation.

User-visible symptom, same minute: I had to send a chat message twice because it appeared not to go through. It was during that window.

Packet level, from a second episode on the other phone the same day: the ARP request arrives on wlan5G, the bridge floods it out ether2 and wlan2.4, and the router's unicast reply leaves via ether3. 42 requests in 90 s, same pattern each time.

That last part matters for the two-FDB explanation. The bridge does receive frames with the client's source MAC on the correct interface (rx ... interface=wlan5G) and does flood them towards the offloaded ports, so the switch chip is seeing them - and the entry still is not moved. So it is not the case that the chip never sees frames from the client.

A false positive worth knowing about, because it cost me a day: the opposite mismatch, registration-table=wlan* with bridge host=ether3 while the client is really on the other AP, is harmless. That is just a stale registration-table entry left after the client leaves the MikroTik radio; the bridge is right and traffic flows. Comparing the two tables therefore over-reports. The reliable signal is the burst of unanswered ARP requests for the gateway.

disable-running-check=yes made no difference: episodes continued the same night and the following days.

So the open question is narrower now: why does source-MAC learning on wlan5G not move the entry off ether3, when the bridge demonstrably receives those frames on wlan5G?

Try updating to the latest version. FDB synchronization gets fixed and/or generally messed with a lot.

If it persists, contact support.

Maintaining the FDB with hardware offload is hard, especially so because many of the simpler switch chips have bugs.

Sorry for the long silence, I wanted to come back with a proper measurement instead of another "it happened again". I've got one now, and it takes both the ethernet port and the second AP out of the picture completely.

Setup, updated: hAP ac^2 (RBD52G-5HacD2HnD), **RouterOS 7.23.3**, **legacy `wireless` package** (`/interface wireless`, not wifi-qcom-ac). `bridge1` holds ether2-ether5 plus wlan2.4 and wlan5G, both radios on the same SSID. `ageing-time=1m`. Full config at the bottom.

**lurker888:** I did both things you suggested. I updated — I was on 7.23.1, I'm now on **7.23.3**, and the episodes continued the same day. And I tried `hw=no` on ether3: **same black hole, same duration.** `disable-running-check=yes` is set on both radios too, also no change. Sorry for the run of negatives.

On hardware offload making FDB maintenance hard — I agree, and that's why I went looking for a case with no switch chip in it at all. I found one, below.

## It happens between the two radios of the same router

I switched the second AP off entirely and lived on the hAP alone for a day. The failure kept happening, and now the stale entry points at **the other radio of the same device**. My wife and I just walk around the flat: when 5 GHz gets weak the phone falls back to 2.4, and back again. Every one of those transitions is a chance to hit this.

I set up a probe sampling every 5 seconds: the wireless registration table (where the client actually is), the bridge host table (where the bridge thinks it is), and the **`.id` of the host entry**, so I can tell a refreshed entry from a re-created one. Here is a clean capture from this morning:

```

07:56:21 reg=wlan2.4 fdb=wlan2.4 id=*8EA aligned, fine

07:56:32 reg=wlan5G fdb=wlan2.4 id=*8EA client moves to 5 GHz

07:57:02 unreachable: 25 ARP requests to the gateway in 90 s, none answered

... 25 consecutive samples, always id=*8EA ...

07:58:31 reg=wlan5G fdb=wlan2.4 id=*8EA

07:58:41 reg=wlan5G fdb=- id=- entry finally disappears

08:01:01 back to normal

```

## The part I find hard to explain

That entry survived **2 minutes and 9 seconds** after the client had left wlan2.4, with `ageing-time=1m`. Same `.id` throughout, so it was never removed and re-created — it is one entry, kept alive.

And then it expired on its own. So ageing is not broken in general: **something was keeping that entry alive while the client was no longer on that port**, and when that stopped, the entry died normally one minute later.

Meanwhile the client was anything but silent — 25 unanswered ARP requests in 90 seconds, arriving on wlan5G.

## I measured the traffic on the stale port. There is none.

I caught another window today at 11:10 and sniffed both ports at once, filtered by the client's source MAC, **separating rx from tx** (`filter-direction`):

```

stale port wlan2.4: rx=0 tx=21 15 s each

real port wlan5G: rx=22 <- positive control

```

**Zero frames ingress on the port the bridge insists the client is on**, while the client is demonstrably transmitting on the other radio in the very same seconds. And the bridge host entry was not flagged `A` (AGED) at that moment either.

Three notes on method, because I got this wrong twice before posting and someone else might too:

- `/tool sniffer quick` is a live redrawing view. If you count output lines you are counting screen refreshes, not packets. The `NUM` column stays at 1 while the screen scrolls past a thousand times. Use the memory sniffer and `/tool sniffer packet print count-only`, which is a real number.

- **The direction filter matters.** Those `tx=21` frames on the stale port are the bridge flooding the client's own broadcasts *out* of the wrong port. Sniff without separating direction and you see the client's MAC on wlan2.4 and conclude it is still transmitting there. It isn't.

- Every run includes a positive control on the port where the client really is. If that reads zero, the instrument is not measuring and the interesting zero means nothing.

So the question narrows to something quite specific: **the entry is kept alive with no ingress on that port at all.** Not "refreshed by the wrong traffic" — refreshed by nothing I can see.

The wireless side, meanwhile, knows perfectly well where the client is: at that moment the registration table showed a single entry on wlan5G, `uptime=1m52s`, `last-activity=50ms`, live counters. No duplicate registration on the other radio — I checked, because a stale *registration* would have been an equally good story and it isn't what's happening. It even logs the move at the exact second:

```

wireless,info CLIENT@wlan2.4: connected, signal strength -73

wireless,info CLIENT@wlan5G: disconnected, registered to other interface

```

Since wireless interfaces are never hardware-offloaded here, mkx, I don't think the chip-FDB / software-FDB split can be the cause of this one — there is no switch chip involved in a wlan-to-wlan move. It may well be a real and separate problem on the ethernet side, I'm not dismissing it, but it can't explain this capture.

## Questions

1. **What keeps a bridge host entry alive when nothing at all is arriving on that port?** That's the crux. Ageing clearly works — the entry does die, eventually, one minute after the episode ends. So what is restarting its timer in the meantime?

2. RouterOS 7 doesn't seem to expose `age` on `/interface bridge host` any more — the properties I get are `.id`, `on-interface`, `bridge`, `dynamic`, `local`, `external`, plus the `A` (AGED) flag, which was not set during the episode. Is there a way to see how old an entry is, or what last refreshed it? I'm currently inferring it from `.id` stability, which is indirect.

3. Should the wireless `registered to other interface` event actively invalidate the host entry? Are there known cases where it doesn't?

4. Before anyone suggests it: yes, I know `wifi-qcom-ac` exists for this board. I tried it a while back and a good part of my house stopped connecting — five air conditioner modules, an ESP32, a Sonoff, a boiler controller, a robot vacuum. Several of them are associated at CCK rates (1, 2, 5.5, 11 Mbps) because they sit at -80 dBm or worse. I've read that the usual culprit is PMF / `management-protection`, which I have disabled on legacy. **I'm going to try it again anyway, next**, since it's the one big variable I haven't changed — I'll report back both on whether the black hole survives the switch and on which of my IoT devices fall off. If someone has actually got a fleet of cheap IoT running on wifi-qcom-ac and knows which settings did it, saying so now would save me a weekend.

One thing before someone spots it in the config: **wlan5G has `bridge-mode=disabled`**. As I understand it that only controls whether the AP accepts MikroTik station-bridge clients, and I have none — everything here is phones and IoT. Happy to be corrected if it means more than that.

One more observation that may or may not be related: during that episode the client sat at **-87 dBm @ 6 Mbps on 5 GHz while standing right next to the router**. That looks wrong on its own and I'm going to chase it separately — but if 5 GHz coverage is poor everywhere, the client keeps bouncing between the two radios, and every bounce is another chance to hit this. It would explain how *often* I see the bug, not the bug itself.

## Config

```

# RouterOS 7.23.3, model RBD52G-5HacD2HnD, package: wireless (legacy)

/interface bridge

add ageing-time=1m name=bridge1 port-cost-mode=short

/interface bridge port

add bridge=bridge1 interface=ether2 internal-path-cost=10 path-cost=10

add bridge=bridge1 hw=no interface=ether3 internal-path-cost=10 path-cost=10

add bridge=bridge1 interface=ether4 internal-path-cost=10 path-cost=10

add bridge=bridge1 interface=ether5 internal-path-cost=10 path-cost=10

add bridge=bridge1 interface=wlan2.4

add bridge=bridge1 interface=wlan5G

/interface bridge settings

# use-ip-firewall: no, allow-fast-path: yes, bridge-fast-path-active: yes

# bridge-fast-forward-packets: 0

/interface wireless

set [ find default-name=wlan1 ] band=2ghz-b/g/n country=italy \

disable-running-check=yes disabled=no frequency=ch11 mode=ap-bridge \\

name=wlan2.4 scan-list=ch1_6_11 ssid=MYSSID wps-mode=disabled

set [ find default-name=wlan2 ] band=5ghz-a/n/ac bridge-mode=disabled \

channel-width=20/40mhz-Ce country=italy disable-running-check=yes \\

disabled=no disconnect-timeout=15s distance=indoors installation=indoor \\

mode=ap-bridge name=wlan5G ssid=MYSSID wps-mode=disabled

/interface wireless security-profiles

set [ find default=yes ] authentication-types=wpa2-psk group-key-update=1h \

mode=dynamic-keys supplicant-identity=MikroTik

# unicast-ciphers=aes-ccm, group-ciphers=aes-ccm, management-protection=disabled

/interface wireless access-list

# a handful of MAC entries pinning IoT devices to wlan2.4, signal-range=-120..120

```

Happy to run any specific test — I have the registration table, the bridge host table and ARP reachability all sampled every minute, so I can catch these windows and time them properly. Just say what would help.