mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-12 06:57:57 +04:00
realtek: l3: skip IPv4 routes without a nexthop device
A blackhole, unreachable or prohibit route has no device behind its nexthop: fib_create_info() refuses one for these types and skips the nexthop check that would find one, so fib_nh_dev stays NULL. otto_l3_fib_add_v4() hands that device to is_vlan_dev() before any test, and otto_l3_fib_check_v4(), which the delete path runs as well, does the same in its variable initialisers. On an RTL9303 with the L3 offload built in, "ip route add blackhole 10.99.8.0/24" oopses in the rtl83xx work queue and panics the box: CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 8070fe3c, ra == 80710594 Workqueue: rtl83xx otto_l3_fib_event_work_do epc : 8070fe3c otto_l3_fib_add_v4+0x1c0/0x794 Kernel panic - not syncing: Fatal exception The faulting load is the priv_flags word is_vlan_dev() tests. Such routes are common on a router, for address space it announces but does not use. Handle them where a route through a nexthop object is already handled, for the same reasons: there is nothing to offload, and the route can still replace one that was, so the entry for its destination is taken out, and a host route is trapped where the host table can hold it. The delete path takes the same exit. Tested on an RTL9303 (Hasivo S1100W-8XGT-SE) with the L3 offload built in. Without this change the command above panics the box; with it, a blackhole /24 stays in the kernel with no entry in hardware, an offloaded /24 replaced by a blackhole loses its entry and gets it back when replaced through the gateway again, a blackhole /32 gets a trap entry in the host table, unreachable and prohibit routes go in as well, and every delete leaves no entry and no oops. RTL839x, which runs this code in a stock build, was not tested. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net> Link: https://github.com/openwrt/openwrt/pull/25513 Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
1 parent
db61fd4444
commit
e59089db5f
1 file changed
+11
-8
@@ -1526,13 +1526,14 @@ static int otto_l3_fib_add_v4(struct otto_l3_ctrl *ctrl, struct fib_entry_notifi
|
||||
struct fib_nh *nh;
|
||||
int port, vlan;
|
||||
|
||||
/* A route through a nexthop object is not offloaded and has no
|
||||
* nexthop array to read, but it can replace a route that is. An
|
||||
* offloaded shorter prefix would forward its traffic, so trap it where
|
||||
* the host table can hold it.
|
||||
/* A route through a nexthop object has no nexthop array to read, and a
|
||||
* blackhole, unreachable or prohibit route has no device behind its
|
||||
* nexthop. Neither is offloaded, but either can replace a route that
|
||||
* is. An offloaded shorter prefix would forward its traffic, so trap
|
||||
* it where the host table can hold it.
|
||||
*/
|
||||
if (info->fi->nh) {
|
||||
dev_dbg(ctrl->dev, "route through a nexthop object, not offloaded\n");
|
||||
if (info->fi->nh || !fib_info_nh(info->fi, 0)->fib_nh_dev) {
|
||||
dev_dbg(ctrl->dev, "route not offloaded: no device or a nexthop object\n");
|
||||
route = otto_l3_route_find(ctrl, info->tb_id, ROUTE_TYPE_IP4UC, info->dst,
|
||||
NULL, info->dst_len);
|
||||
if (route)
|
||||
@@ -1646,8 +1647,10 @@ static int otto_l3_fib_del_v4(struct otto_l3_ctrl *ctrl, struct fib_entry_notifi
|
||||
struct in6_addr gw;
|
||||
struct fib_nh *nh;
|
||||
|
||||
/* A route through a nexthop object holds at most a trap entry */
|
||||
if (info->fi->nh) {
|
||||
/* A route through a nexthop object or without a device holds at most a
|
||||
* trap entry
|
||||
*/
|
||||
if (info->fi->nh || !fib_info_nh(info->fi, 0)->fib_nh_dev) {
|
||||
route = otto_l3_route_find(ctrl, info->tb_id, ROUTE_TYPE_IP4UC, info->dst,
|
||||
NULL, info->dst_len);
|
||||
if (route)
|
||||
|
||||
Reference in new issue
Block a user