Files
openwrt/target/linux
Gennaro Cimmino 404823678f realtek: l3: rtl839x: route with the egress device's MAC
On RTL839x every routed frame leaves with the switch's own MAC,
whatever device the route goes out of, and frames to a device with a
MAC of its own are not routed: every ROUTING_SA_CTRL entry the driver
writes (0 to 14) holds the switch's MAC, and every ROUTING row names
entry 0 (#25768, items 3 and 4).

The 16 entries are the source MACs a ROUTING row names (SW_MAC_IDX,
Realtek GPL SDK, dal_cypress_l3_routeEntry_set()) and, as measured,
also the MACs whose frames the switch routes. Entry 0 stays the
switch's MAC (dal_cypress_l3_init()). Any other MAC that a route goes
out of a device with takes an entry, per MAC and held by the routes
through it, the on-link prefix included, so a device routes on its MAC
while it has an address, if an entry was free when it got it. A
ROUTING row is now keyed on the gateway's MAC and that entry. Unused
entries hold FF:FF:FF:FF:FF:FE, as the SDK leaves them.

What the hardware cannot do traps. A route through a gateway that
finds no entry free traps, and asks again on the gateway's next
neighbour update. Two devices with different MACs on one VLAN reach a
gateway through one L2 entry, which can name only one of their rows:
the routes already forwarding keep it. A device that takes a new MAC
has its entry rewritten when only its routes hold it and no other
entry has the new MAC; otherwise its routes move to an entry for the
new MAC, those through a gateway trapping until a resolve gives them
their new row, and the old entry, still routed, is given up only with
the rows that name it.

Measured on an HPE 1920-48G (RTL8393), on main f29dfe25ba with the
previous patch and bench debugfs files, before the rebase onto
e5ec5e199f; 8 echo requests per case, forwarding off, switch.3 and
switch.7 with MACs of their own (M3, M7), gateway G in VLAN 3 and, with
the same MAC, in VLAN 7, sending now and then as a live gateway does:
- from VLAN 7 to M7, route out of switch.3: 8/8 at G, TTL 63, source
  M3 (on the #25808 image: 0/8, all to the CPU)
- routes via G out of switch.3 and switch.7: two ROUTING rows, 8/8
  with M3 and 8/8 with M7
- switch.3 down: its entry freed, the switch.7 route still 8/8 with
  M7; up again: M3 back, 8/8
- switch.7 to a new MAC: its entry rewritten in place, 8/8 with the
  new MAC, the switch.3 route unchanged
- switch.7 to M3, which switch.3's entry holds: its routes moved to
  that entry, its old one freed, both routes 8/8 with M3
- with one entry held, 16 more VLAN devices with MACs of their own:
  the entries ran out after 14, and a gateway route out of a device
  without one trapped; once the others were gone it took an entry on
  its next neighbour update (debugfs and register reads, no traffic;
  G was never on those VLANs, so before e5ec5e199f its routes there
  got an invented L2 entry, and on main they trap for want of one:
  only the switch MAC entries were checked)
- rerun from #25805 and #25808: two prefixes in both orders, one
  gateway for two routes, neighbour loss: same results

Other RTL839x boards: routes keep entry 0, as before, while every
device they go out of has the MAC eth0 had at probe. A device with
another MAC now takes an entry, and frames to it are routed by the
switch instead of the CPU.

RTL930x sets no set_switch_mac: its routes take no entry, and its
netdev notifier path is unchanged. Compile-tested on rtl930x. RTL838x
and RTL931x have no setup, so their FIB and neighbour events are ignored
and none of this runs there.

Not tested: two devices with different MACs on one VLAN, a move to a
new entry, a device going back to the switch's MAC, a failed ROUTING
row write.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25822
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-12 13:38:39 +02:00
..
2026-10-04 15:57:54 +02:00
2026-10-06 18:35:40 +01:00
2026-10-04 15:57:54 +02:00
2026-07-23 09:08:57 +02:00
2026-10-01 00:49:54 +02:00
2026-10-06 18:35:40 +01:00
2026-10-06 15:11:36 +02:00
2026-10-01 00:50:42 +02:00
2026-08-13 00:22:31 +02:00
2026-10-01 00:49:54 +02:00
2026-10-06 18:35:40 +01:00
2026-10-06 18:35:40 +01:00