Unable to route LAN to hosts behind a switch

I've nearly finished migrating a x86 APU router with Debian to a Banana Pi BPI-R3 with OpenWRT 24.10.5, and am struggling to route LAN traffic (192.168.25.0/24) to hosts behind a switch. The switch is wired to the BPI-R3 via a 192.168.110.1 interface and can be reached by LAN hosts at 192.168.110.2. The hosts my LAN cannot reach are on 192.168.35.0/24, which is part of a VLAN my switch manages.

I can ping the switch and access its web management UI from my LAN, and the switch can ping any host on the 192.168.35.0 network, but my LAN can't reach anything in that same network. This connection previously worked on the APU, and nothing on the switch has changed.

Here's a diagram of my setup:

And my BPI-R3 configurations:

root@bpi-r3-router:~#  cat /etc/config/network 
# irrelevant blocks removed

config device
	option name 'br-wan'
	option type 'bridge'
	list ports 'eth1'
	list ports 'wan'
	option ipv6 '0'

config device
	option name 'eth1'
	option macaddr '<snipped>'

config device
	option name 'wan'
	option macaddr '<snipped>'
	
config interface 'wan'
	option device 'br-wan'
	option proto 'dhcp'
	option peerdns '0'

config interface 'wan6'
	option device 'br-wan'
	option proto 'dhcpv6'

config device
	option name 'br-lan'
	option type 'bridge'
	option ipv6 '0'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'sfp2'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.25.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config interface 'switch_basement'
	option proto 'static'
	option device 'lan2'
	option ipaddr '192.168.110.1'
	option netmask '255.255.255.0'

config route
	option interface 'lan'
	option target '192.168.25.0/24'
	option gateway '192.168.25.1'

config route
	option interface 'switch_basement'
	option target '192.168.110.0/24'
	option gateway '192.168.110.1'

config route
	option target '192.168.35.0/24'
	option gateway '192.168.110.1'
	option interface 'switch_basement'
	
config rule
	option in 'lan'
	option src '192.168.25.0/24'
	option ipproto '6'
	option out 'switch_basement'
	option dest '192.168.35.0/24'
	option lookup 'main'
	option disabled '1'
root@bpi-r3-router:~#  cat /etc/config/firewall 
# irrelevant blocks removed

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'lan'

config zone
	option name 'wan'
	list network 'wan'
	list network 'wan6'
	option input 'DROP'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'

config zone
	option name 'switch_basement'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option family 'ipv4'
	list network 'switch_basement'
	option masq '1'
	option log '1'

config forwarding
	option src 'lan'
	option dest 'wan'
	
config forwarding
	option src 'switch_basement'
	option dest 'wan'

config forwarding
	option src 'lan'
	option dest 'switch_basement'

config nat
	option name 'nat-lan-wifi'
	option family 'ipv4'
	list proto 'all'
	option src 'wan'
	option src_ip '192.168.25.0/24'
	option target 'MASQUERADE'

config nat
	option name 'nat-switch-basement'
	option family 'ipv4'
	list proto 'all'
	option src 'wan'
	option src_ip '192.168.110.0'
	option target 'MASQUERADE'
	option device 'lan2'

config nat
	option name 'nat-wifi-to-switch-basement'
	option family 'ipv4'
	option src 'switch_basement'
	option src_ip '192.168.25.1'
	option dest_ip '192.168.110.1'
	option target 'MASQUERADE'
	option device 'br-lan'
	list proto 'all'

config nat
	option name 'nat-wifi-to-basement-servers'
	option family 'ipv4'
	option src 'switch_basement'
	option target 'MASQUERADE'
	option device 'lan2'
	option dest_ip '192.168.35.0/24'
	list proto 'all'
	option enabled '0'

config rule
	option src 'lan'
	option dest 'switch_basement'
	option name 'wifi-to-switch-basement'
	option direction 'out'
	option device 'br-lan'
	option family 'ipv4'
	list src_ip '192.168.25.1'
	list dest_ip '192.168.110.1'
	option target 'ACCEPT'
	
config rule
	option src 'lan'
	option dest 'switch_basement'
	option name 'wifi-to-basement-servers'
	option family 'ipv4'
	list dest_ip '192.168.35.0/24'
	option target 'ACCEPT'
	list src_ip '192.168.25.1'
	option enabled '0'
root@bpi-r3-router:~#  ip route
default via <snipped> dev br-wan  src <snipped>
<snipped> dev br-wan scope link  src <snipped> 
192.168.25.0/24 via 192.168.25.1 dev br-lan 
192.168.35.0/24 via 192.168.110.1 dev lan2 
192.168.100.0/24 via 192.168.100.1 dev lan1 
192.168.110.0/24 via 192.168.110.1 dev lan2

I originally had this route on my APU:

ip route show
...
192.168.35.0/24 via 192.168.110.2 dev enp3s0

But when I try to configure the same route on the BPI-R3, I get this error:

root@bpi-r3-router:~# ip route add 192.168.35.0/24 via 192.168.110.2 dev lan2
ip: RTNETLINK answers: Network unreachable

I can create and modify that same route in LuCI under Network > Routing, but it doesn't show in Status > Routing. The route only appears in Status > Routing when I use 192.168.110.1, which gives these results for ping and traceroute:

PING 192.168.35.2 (192.168.35.2): 56 data bytes

--- 192.168.35.2 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss


traceroute to 192.168.35.2 (192.168.35.2), 20 hops max, 46 byte packets
 1  *
 2  *
 3  *
 4  192.168.110.1  123.166 ms !H

Sorry for the long post, and thanks in advance for any thoughts and advice.

All of this can be deleted:

Remove masquerading on the switch_basement zone:

I'm not sure what your goals are here, but it seems that all of these can be deleted, too:

restart and test again.... does that fix things?

I also meant to say: you should upgrade to 25.12

Thanks for the guidance. I was hoping to update OpenWRT to the latest version after getting my base install sorted out. For now, I had to keep the routes because removing the one for 192.168.110.0/24 made the switch inaccessible. Connections from the BPI-R3 to the switch timed out until that route was restored. I tried removing the route for 192.168.35.0/24 on its own, but then my traceroute attempts to 192.168.35.x timed out. I'm sure it's because the router was attempting to reach those hosts through the WAN.

I removed masquerading on the switch_basement zone and disabled the NAT and traffic rules you mentioned, but still couldn't connect anything on 192.168.25.x to 192.168.35.x after saving and rebooting. As for the goals with my configurations, I was trying to set up the BPI-R3 exactly as I had my old APU, which I configured nearly 8 years ago. Given your pointers, the APU must have worked in spite of how I built it up. :laughing:

Just to be sure, is there any way to define a route with 192.168.110.2 as the gateway for LAN traffic going to 192.168.35.0/24? It's clear to me that the router is trying to reach 192.168.35.x directly from 192.168.110.1, rather than sending through the switch.

Ah... sorry, I think I misread your original intent a bit.

Is the TP-Link switch a true L3 switch? What is the model of this device? (And yes, if you have the switch routing, you'll need to have the route defined on the main router.) That said, why are you routing on the switch as compared to setting up the network on the main router and then using VLANs at the switch?

No problem. Trying to get on the same page is half the fun with these kinds of troubleshooting posts!

The TP-Link is an old Jetstream T2600G-28MPS, and it has L2 and L3 capabilities. I had routes on the switch because I wanted to squeeze a handful of different networks into the single APU interface, and wasn't sure how to achieve that solely on the APU at the time. I never got around to loading the Jetstream with a mass of networks, so it currently just has one port for trunk (set to 192.168.110.2), and a small group of ports dedicated to 192.168.35.x. Trunk and the 192.168.35 network are on separate VLANs, and these routes are in place:

Protocol	Destination Network  Next Hop        Distance	Metric	Interface Name
Static      0.0.0.0/0            192.168.110.1   1          0       VLAN1
Connected   192.168.110.0/24     192.168.110.2   0          1       VLAN1
Connected   192.168.35.0/24      192.168.35.1    0          1       VLAN2

The switch always worked like that, but I'm sure it's long overdue for reconfiguration. The basic functionality I wanted to carry into the BPI-R3 was to have a single interface capable of connecting to a unique switch with multiple networks behind it. If I had all the routing the 192.168.35.0/24 network on the BPI-R3, wouldn't the switch_basement interface only be able to communicate with a single VLAN / network on the downstream switch?

Edit to fix the switch_basement name typo, and to rethink my last question.

So yes, that switch is capable of handling the routing between the subnets. L3 switching can be valuable when you have a high bandwidth inter-vlan routing requirement that might saturate the link to the router and/or negatively impact your main router's throughput to the Internet.

That said, my personal preference is to route on the router (instead of the switch) if the bandwidth issues mentioned above are not a concern, but of course using the L3 switching capacity is valid, too.

So looking back at the config again...

This is unnecessary since both of these networks are directly connected to/defined on this router:

This one is necessary, but is slightly wrong:

The correct gateway here is the IP address of the switch itself (192.168.110.2) since that is the device that is the gateway to the 192.168.35.0/24 network.

This can be deleted:

As I had said earlier, you most likely don't want masquerading here (and also, you'll likely want to remove the logging):

Masquerading is already handled for your wan by the wan firewall zone... you don't need to define any additional masquerading, so you can delete this:

And I'm assuming you want symmetric routing, so masquerading here is also unnecessary (delete):

Once masquerading is disabled, this rule has no purpose and can be deleted:

and this rule, too:

Try those changes and see if it works.

Alternatively, you can define the VLANs on the main router and disable the L3 features on the switch.

Thanks for pointing out what could be cleaned up. I implemented those suggestions, but had to restore the switch_basement route to make my switch remain accessible. Pings and traceroutes to the switch at 192.168.110.2 failed until I put the switch_basement route back in place. I also left the LAN route intact just in case, but am open to removing that after getting LAN connections to 192.168.35.x working.

Here are my current configurations:

root@bpi-r3-router:~# cat /etc/config/network 
# irrelevant blocks removed
config device
	option name 'br-lan'
	option type 'bridge'
	option ipv6 '0'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'sfp2'

config device
	option name 'br-wan'
	option type 'bridge'
	list ports 'eth1'
	list ports 'wan'
	option ipv6 '0'

config device
	option name 'eth1'
	option macaddr '<snipped>'

config device
	option name 'wan'
	option macaddr '<snipped>'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.25.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config interface 'wan'
	option device 'br-wan'
	option proto 'dhcp'
	option peerdns '0'

config interface 'switch_basement'
	option proto 'static'
	option device 'lan2'
	option ipaddr '192.168.110.1'
	option netmask '255.255.255.0'

config route
	option interface 'lan'
	option target '192.168.25.0/24'
	option gateway '192.168.25.1'

config route
	option interface 'switch_basement'
	option target '192.168.110.0/24'
	option gateway '192.168.110.1'

config route
	option interface 'switch_basement'
	option target '192.168.35.0/24'
	option gateway '192.168.110.2'
root@bpi-r3-router:~# cat /etc/config/firewall 
# irrelevant blocks removed
config zone
	option name 'wan'
	option input 'DROP'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	
config zone
	option name 'switch_basement'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option family 'ipv4'
	list network 'switch_basement'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'lan'

config forwarding
	option src 'lan'
	option dest 'wan'

config forwarding
	option src 'lan'
	option dest 'switch_basement'

config forwarding
	option src 'switch_basement'
	option dest 'wan'
root@bpi-r3-router:~# ip route
default via <snipped> dev br-wan  src <snipped> 
<snipped> dev br-wan scope link  src <snipped>
192.168.25.0/24 via 192.168.25.1 dev br-lan 
192.168.110.0/24 via 192.168.110.1 dev lan2

The routing table highlights one of my original problems where the 192.168.35.0/24 via 192.168.110.2 rule shows in Network > Routing and /etc/config/network, but doesn't appear in Status > Routing. Unless I'm missing something, I don't seem to have a way to make the route appear in the routing table when the next hop of 192.168.110.2 is defined.

Side note in case it helps someone avoid the same mistake: I took inspiration from the ip-link man page and made an alias interface within LuCI pointing @switch_landing to a static address of 192.168.110.2. I then created a route defining 192.168.110.2 as the next hop for the 192.168.35.0/24 network on @switch_landing, and saw that route added to my routing table in Status > Routing.

Strangely, an automatically generated route was also added at the top of my table, effectively shuffling WAN traffic to the 192.168.110.x network. That extra route broke internet connections until I removed the alias interface and its route, and rebooted the BPI-R3 (tearing down my changes wasn't enough to reconnect). No idea if connecting to the network behind my switch would've worked with that alias interface since internet access took priority.

hmmm...

This should specifically not be necessary.

Let's see the output of this:

ubus call system board

Sure thing. Here's the output:

root@bpi-r3-router:~# ubus call system board
{
	"kernel": "6.6.119",
	"hostname": "bpi-r3-router",
	"system": "ARMv8 Processor rev 4",
	"model": "Bananapi BPI-R3",
	"board_name": "bananapi,bpi-r3",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "24.10.5",
		"revision": "r29087-d9c5716d1d",
		"target": "mediatek/filogic",
		"description": "OpenWrt 24.10.5 r29087-d9c5716d1d",
		"builddate": "1766005702"
	}
}

You should consider upgrading to 25.12

Meanwhile, when you remove this:

do you also see the route disappear in route?

Will do on the firmware update. I'll take care of that tomorrow evening. As for the mentioned route, it is properly removed when I disable it in LuCI:

root@bpi-r3-router:~# ip route
default via <snipped> dev br-wan  src <snipped> 
<snipped> dev br-wan scope link  src <snipped> 
192.168.25.0/24 via 192.168.25.1 dev br-lan 

The 192.168.25.0/24 entry appears because I left its rule intact for the time being.

Do you have PBR installed or anything similar? It doesn't make sense that the route is not automatically created as a function of the interface.

No, though I considered doing that based on several posts I found during my own troubleshooting. My current package list is just what was included with the standard SD card image.

Are you able/willing to reset to defaults (rewrite the card if you are using ext4) and start fresh? Something just doesn't seem right and I can't figure out why, but a default config should give us better chances of success.

Of course, you can make a backup before you do anything (easy to restore), or even better, if you have another card, you could leave your current card intact and try the clean default install with a new one.

Things are getting interesting with my setup. I tried to flash the latest available sysupgrade firmware, but I got this error from System > Backup / Flash Firmware > Flash new firmware image (line breaks added):

Image check failed:

Fri May 29 20:10:27 CDT 2026 upgrade: The device is supported, but the config is 
incompatible to the new image (1.2->1.3). Please upgrade without keeping config 
(sysupgrade -n). Fri May 29 20:10:27 CDT 2026 upgrade: First sfp port renamed from 
eth1 to sfp1 Image check failed. 

I can't go through with the upgrade without dropping my configs and selecting Force upgrade. I also can't manually rename the eth1 device to sfp1 in LuCI to get around that error. I'm confident that I have the right image for my device, but should I take another step before proceeding with the upgrade?

EDIT: Assuming there isn't another troubleshooting step to take, I can definitely look into resetting to defaults after completing the firmware upgrade.

The upgrade warning is fortunately pretty clear, and it does accomplish the reset that I was suggesting. So yes, I think it would make sense to proceeed (after you make a backup of your existing config -- you can always roll back to the previous version and then restore this config).

Alternatively, if you have another SD card, you can keep this one unaltered and simply swap to a new one after writing the image to it from your computer. This makes it painless to go back to the previous firmware + config since it becomes as simple as swapping the card.

I ran into a snag with reimplementing my configurations, but upgrading to the latest release fixed my issue. The one thing I missed was removing the lan2 device from the bridged ports for br-lan after upgrading. I couldn't ping or reach my switch at 192.168.110.2 until doing that, and I didn't think to capture the details of my original br-lan device before upgrading.

You're right that the routes now populate without my involvement on the new firmware. I only had to define this route:

192.168.35.0/24 via 192.168.110.2 dev lan2 

The rest was automatically sourced from my interface definitions:

root@bpi-r3-router:~#  ip route
default via <snipped> dev br-wan  src <snipped> 
<snipped> dev br-wan scope link  src <snipped> 
192.168.25.0/24 dev br-lan scope link  src 192.168.25.1 
192.168.35.0/24 via 192.168.110.2 dev lan2 
192.168.110.0/24 dev lan2 scope link  src 192.168.110.1

And best of all, I can reach the hosts on the 192.168.35.0 network without issue. Which is nice because some of those needed their own upgrades!

The BPI-R3 now fully covers the functionality I had with my APU, which can finally be retired. I'm curious what about my previous BPI-R3 firmware was causing the routing behavior that I shared, but that may just be a quirk of my original install.

More importantly, thank you for your continued help throughout this thread. I was completely stumped after my own research fell short of a fix, and greatly appreciate your efforts to get my system where it needed to be.