mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-25 16:53:49 +04:00
On RTL839x a route through a gateway the switch holds no L2 entry for gets one invented by otto_l2_nexthop_add(): static, with the don't-care port. The gateway is then cut off from the switch, and what the route should forward goes to the CPU instead. Measured on an HPE 1920-48G (RTL8393), mainf29dfe25ba, gateway G on a bridge VLAN behind lan48, with a permanent neighbour and a MAC the switch had not seen, 8 echo requests to a destination behind it, forwarding off: - G's L2 entry was written static, port 63 - G got 0 of 3 replies from the switch; the 8 echo requests reached the CPU, none reached G - with the neighbour made dynamic the entry stayed as it was - with the route removed G got 3 of 3 replies, and the switch learnt it on port 47 Setting lan48's static move action to forward did not restore it, so that alone does not explain it; the mechanism is not known. RTL930x stopped inventing that entry in138fabb79f("realtek: l3: do not invent an L2 entry for a next hop") wherever a route can trap, and since #25805 an RTL839x route can. Require an entry the switch already holds on every family: the route traps until the switch learns the gateway from the traffic the CPU routes, and a later neighbour update programs it. Nothing asks otto_l2_nexthop_add() to invent an entry any more, so the flag and the invented entry go. A route trapped for want of one is now logged on RTL839x as on RTL930x. On RTL839x an L2 entry that is a next hop already is now pointed at its gateway's ROUTING row as on RTL930x, one row per gateway MAC sincec282dd1f4d. The same case with this change: no entry written, the route trapped, G got 3 of 3 replies and was learnt on port 47; the 8 echo requests reached the CPU and, with forwarding on, G through the kernel, TTL 63. With the neighbour made dynamic the route forwarded on the learnt entry, 8 of 8 at G, none at the CPU. The cases from #25805 rerun (two prefixes in both orders, neighbour loss): same results. Since that run only the log line and comments changed. As138fabb79fsays, a route through a permanent neighbour the switch had not learnt stays with the CPU, since such a neighbour sees no update: measured here too, it stayed trapped after G was learnt, until the neighbour was made dynamic. Also as on RTL930x, a route that claims an entry the switch learnt again after a flush counts itself on top of the count the flushed entry left, so that entry can stay a next hop once the route is gone; not tested. RTL930x: no change, it already required such an entry. RTL838x and RTL931x have no setup, so their FIB and neighbour events are ignored and none of this runs there. Compile-tested on rtl930x. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net> Link: https://github.com/openwrt/openwrt/pull/25824 Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>