Link-Aggregation in LAN with VLANs

you have a vlan aware bridge with DSA at least this is the recommended way. One bridge with one or more vlans.

Try to configure your lacp bond with UCI otherwise Openwrt is not aware of this interface.
Then you attach this bond interface as tagged to each vlan where needed. Makes sense?

Yes and no :frowning: Sorry, I am tired, I am trying to figure these things from disparate articles and posts, many of which are probably well outdated and many of which very likely refer to other types of devices.

So how exactly do I configure the LACP bond with UCI? I'm asking because I'm genuinely in the dark here, I've just read https://openwrt.org/docs/guide-user/base-system/uci and I can't see how I can configure the bond using it.

Otherwise, even if created using CLI commands the bond0 device does show up in LUCI, so I'm not sure I see your point that "otherwise Openwrt is not aware of this interface".

"Then you attach this bond interface as tagged to each vlan where needed" - This kinda makes sense, unfortunately I am locked out every time I try to configure it, not sure whether it's because I'm trying something really stupid or maybe just the order and the timing of updating both the router config and the switch config

LE: at least I managed to get a serial console over an USB adapter running, so when I'm locked out I can manually restore the /etc/config/network file and reboot. For some reason that eludes me the 90s LUCI rollback doesn't actually roll back anything :frowning:

I will try to reply in more detail, besides that:

Chances are that if something triggers a network restart then the bond will be detached from the bridge.
For debugging and stuff, I would propose you try to use IPv6 link local address for your ssh session. Often this still works even if the network went south. Saved me in the past.

Thanks for your continued help. I am fine with the serial console for now, I am really struggling though to figure out what I need to do in LUCI. I created a bunch of bond0.10, bond0.20, ... devices for my intended VLANs, and I literally just noticed that there is also a create interface bonding-bond0 menu, too. I reckon this is where I can define it in LUCI? But I'm still trying to guess what I need to plug into it so that I don't screw up, again.

Ok, I think I made some progress... hopefully in the right direction!
Once I found the LUCI interface to add the bonding interface I could at long last make some sense of this post Link-Aggregation in LAN with VLANs - #6 by Ars3n above here. I created the interface, it ended up named bond-bond0. (I find this confusing, but hey!) I also had to assign it a static IP address, I gave it a 10.x.y.z private address, hoping that I never actually have to use it for anything else. Then I deleted all the previously created devices bond0.10, bond0.20 etc based on bond0, and I've recreated them based on this new bond-bond0, so they ended up named bond-bond0.10, bond-bond0.20 etc. Then, I used the new bond-bond0.10 device to create a new interface, named mgmt (with its own static private IP address and DHCP server), and also created a new firewall zone called mgmt, and set the forwarding rules between it and lan and wan. This whole ping-pong between device-interface-device-interface really made my head spin.

Now, the important question: how do I trunk this new mgmt VLAN (and in the future the other VLANs, too) over the LACP link group to the switch?

Since your last post is older than two weeks and I'm trying to accomplish almost the same I'm curious if you've made any progress.

My goal is just to aggregate 3 ports for my VLANs on my managed switch. Can't be that hard right? It's working fine without the LAGG: So I've installed the package luci-proto-bonding, created a new bond0 interface with its slaves via luci, added this LAGG to the VLAN aware bridge where all physical ports of my switch were bridged and removed the ethernet ports that were used in bond0 from bridge.
Afterwards a new bridge option tab appeared in bond0 and I could see some kB of packets being sent on this interface.

However 802.1q VLANs are still not working.
I tried creating them using bond0 as base device but I couldn't get any connection. Doesn't make that much sense but then I tried creating those VLANs via the VLAN filtering tab of the bridge like I did without the bond which also resulted in non working VLANs. Again without the LAGG it's working fine this way.

The LAGG from the switch is connected to an OPNsense that uses the same settings like I configured in the bond interface (bonding policy: 802.3ad,
transmit hash policy: l3+4). I've also experimented with some other settings regarding the hash policy and adding/removing ports from the bridge but nothing worked.

Yes, I got them working. On the NanoPi R4S running OpenWrt 22.03.5 with DSA the LAG is flawless; on a Linksys MR8300 running the new OpenWrt 23.05.0 (to use the same DSA) it is giving me some headaches - it connects just fine after a reboot but sometimes if I change something completely different in the network config it leaves the bond interface down. I couldn't figure out exactly why, I'm still struggling to find out.

A few hints that I really wished I knew when I started, they would have saved me a couple of days of sheer frustration:

  • required packages: kmod-bonding luci-proto-bonding mii-tool ip-full git (I'm not 100% sure of git but ip-full is essential)
  • reboot once after installing them
  • do not waste any time writing a script to create the bond, luci can do this for you (this was a big time waste for me as I started by reading some outdated info from various posts, but I think you're not doing this so you should be ok)
  • use a short name for the bond interface, e.g. bond0 (it will become bond-bond0 anyway). longer names can lead to silent failures which are very difficult to troubleshoot
  • are you sure you want to use layer 3+4 hashing? it's not standard for 802.3ad
  • you can easily tell if your router uses DSA by checking for the swconfig linux command in the cli, or for the "Switch" configuration page under "Network" in luci. If your router has them it is NOT using DSA
  • for routers using DSA, add the new bond-bond0 interface to the vlan aware bridge (e.g. br-lan) and remove from the same bridge any interfaces that you used to create the bond (you said you already did this so you should be ok)
  • tick the "enable vlan filtering" box under the "bridge vlan filtering" for the vlan aware bridge (br-lan) and start adding the vlans one by one; set each of them as tagged on the bond-bond0 interface, as untagged and primary vlan for the ports where you want to "break them out" to regular devices (e.g. PCs). make sure each port is marked primary vlan for only one vlan
  • change the lan interface to use one of the br-lan.xy interfaces you created by adding the vlans (xy being the vlan you want for lan). same goes for other vlans & networks, i.e. if you want you can add new networks by using the available br-lan.xy interfaces. you can set the new interfaces as static IP, dhcp client and even unmanaged (e.g. I used both dhcp client and unmanaged for the MR8300 since I want it used only as a "dumb" AP, and they work just fine)
  • if the managed switch is also running OpenWrt then I reckon it should be a similar process; if it's not running OpenWrt then check its manual on how to set it up for LAG

I think this is it, in a nutshell. Let me know if you still struggle, I will try to help if I can but tomorrow as it's 04:15am here now :frowning:

2 Likes

Ah, something else: it's very useful to have a serial console to the router while you're playing with this, you can use it to quickly revert the config if you get disconnect from the network and luci gets confused to the point it doesn't automatically revert your unconfirmed change.

I just want to advertise again that IPv6 link local is mostly always an option too because it's really hard to screw up the config that hard that (if the interface is at least up) to not have a link local address. Or just leave one interface without a special config which also results that it is up and has an LLA. Then you can ssh to the router via the LLA.

1 Like

Thanks for your guide, I tried everything again.
Unfortunately it's still not working.

required packages: kmod-bonding luci-proto-bonding mii-tool ip-full git (I'm not 100% sure of git but ip-full is essential)

I had the package luci-proto-bonding installed and it had the dependencies proto-bonding and kmod-bonding, ip-full was preinstalled. So I just had to install mii-tool and git. I doubt git is necessary and also gave me an error when I installed it: "Unable to execute opkg install command: SyntaxError: Unexpected end of JSON input". However I tried reinstalling and got the message it was already installed as root and it showed under installed packages in LUCI.

use a short name for the bond interface, e.g. bond0 (it will become bond-bond0 anyway)

I used "lagg0" before but also tried "bond0" now but shouldn't matter because it has the same length. Still I can't confirm the "it will become bond-bond0 anyway" part. Mine stayed at "bond-lagg0" when I named it "lagg0".

are you sure you want to use layer 3+4 hashing? it's not standard for 802.3ad

I read the specs of my switch and it's able to make use of l3+l4 for hashing. But I changed it to l2+l3 on both sides (switch and OPNsense) again.

you can easily tell if your router uses DSA by checking for the swconfig linux command in the cli, or for the "Switch" configuration page under "Network" in luci. If your router has them it is NOT using DSA

It uses DSA. It's a Netgear G308T with OpenWrt 23.05.0 installed on it.

make sure each port is marked primary vlan for only one vlan

This shouldn't be necessary in OpenWrt for me since I only have max one untagged VLAN per physical port. I know primary VLAN should be the same as port tagging but the documentation says: "PVID: Primary VLAN ID makes the specified VLAN ID assigned to the interface the primary one. Untagged ingress will be assigned to the specified VLAN ID. This is not useful if only a single VLAN ID is assigned to the interface as untagged." (https://openwrt.org/docs/guide-user/network/dsa/converting-to-dsa#local)

change the lan interface to use one of the br-lan.xy interfaces you created by adding the vlans (xy being the vlan you want for lan). same goes for other vlans & networks, i.e. if you want you can add new networks by using the available br-lan.xy interfaces. you can set the new interfaces as static IP, dhcp client and even unmanaged (e.g. I used both dhcp client and unmanaged for the MR8300 since I want it used only as a "dumb" AP, and they work just fine)

It was preconfigured that LAN uses switch.1 (switch is the name of the bridge device and 1 the VLAN) and it can stay this way so I have direct access to my LAN when using an untagged VLAN 1 port.
For me it shouldn't be necessary to create new devices and interfaces since it's just a switch. So I unchecked the Local checkbox in Bridge VLAN filtering for all VLANs except VLAN 1. For testing purposes I checked it too.
However I used this on my dumb APs to create unmanaged interfaces so I was able to create SSIDs for every VLAN.

Let me know if you still struggle, I will try to help if I can

Very nice. Do you want me to post some config files from OPNsense and my OpenWrt switch or something else?

And two more questions:
Did you check the force link checkbox in the bonding interface? I tried both but I'm not sure what it does exactly.
Have you set an IP address from your network for this interface? I just set it to 10.0.0.1 since it's not in my network range and it also wasn't necessary to specify an IP address in my OPNsense firewall/router.

By "it will become bond-bond0 anyway" I meant bond0 will become bond-bond0. Same way your lagg0 became bond-lagg0. But apart from the different names there are no other differences between them.

Ok, so DSA and no issues with hashing and primary VLANs. So I assume that:

  • because of DSA you can see the 8 individual Ethernet ports of the G308T switch as separate OpenWrt devices / linux eth interfaces
  • in Luci, under Network / Interfaces / devices / switch you already took out (unselected) the individual devices (G308T switch ports) that you used to create lagg0

If so then this is what I would do (if you haven't already done so):

  • in Luci, under Network / Interfaces / devices / switch, add bond-lagg0 to the bridge (next to the existing individual G308T Ethernet ports)
  • in Luci, under Network / Interfaces / devices / switch / "bridge vlan filtering" tick the "enable vlan filtering" box and add the required vlans one by one, configuring tagged /untagged ports (you seem to know how to do this). You should also see bond-lagg0 here, for which you should Tag all VLANs
  • under Network / Interfaces / LAN change the 1 in switch.1 with the VLAN id you want to use for LAN; the other switch ports should be part of the VLANs you assigned them to.

And this should be it. I feel the /etc/config/network file from the openwrt switch, the /proc/net/bonding/lagg0 "file" and the output of the ifconfig -a linux command would be helpful to understand a bit what you're seeing there (you could also have a look at the files in /sys/class/net/bond-lagg0/bonding/, e.g. active_slave) Please keep in mind though that I'm no OpenWrt expert myself, only a couple of weeks ago I was here asking the same questions!

And yes:

  • I did check the "force link checkbox" for bond0 (lagg0 for you)
  • I also assigned a dummy private IP address for the bond0 interface, otherwise it would not allow me to create it. As far as I can tell I never get to use it so it really doesn't matter

Also, please make sure you have either miimon specified (100 should be ok) OR set both arp_interval and arp_ip_target. Mine works with miimon 100, so I'm not exactly sure how to set up the arp monitoring for the LA. One page where I found this described is https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/networking_guide/sec-using_channel_bonding , another was https://elixir.bootlin.com/linux/v4.14.63/source/Documentation/networking/bonding.txt where I found this: "Very few devices do not support at least miimon, so there is really no reason not to use it" so I reckon you should be ok with miimon on the G308T. The last parameter I would check would be use_carrier ; from the same page above:

use_carrier
	Specifies whether or not miimon should use MII or ETHTOOL
	ioctls vs. netif_carrier_ok() to determine the link
	status. The MII or ETHTOOL ioctls are less efficient and
	utilize a deprecated calling sequence within the kernel.  The
	netif_carrier_ok() relies on the device driver to maintain its
	state with netif_carrier_on/off; at this writing, most, but
	not all, device drivers support this facility.

	If bonding insists that the link is up when it should not be,
	it may be that your network device driver does not support
	netif_carrier_on/off.  The default state for netif_carrier is
	"carrier on," so if a driver does not support netif_carrier,
	it will appear as if the link is always up.  In this case,
	setting use_carrier to 0 will cause bonding to revert to the
	MII / ETHTOOL ioctl method to determine the link state.

	A value of 1 enables the use of netif_carrier_ok(), a value of
	0 will use the deprecated MII / ETHTOOL ioctls.  The default
	value is 1.

Good luck!

1 Like

Thank you again. I did everything you said above already before you wrote your post apart from activating and setting miimon polling intervall to 100. And I haven't set my LAN to another VLAN because I want VLANs (LAGG) and LAN for management on seperated physical ports.

To reduce complexity I just added one VLAN and tried to access VLAN 10 via my test port 7 with no luck. Port 8 is my dumb AP which worked great with all VLAN when there was no LAGG.

I'm confused that it says round robin in bonding mode ("Bonding Mode: load balancing (round-robin)") even though I set it to 802.3ad ("option bonding_policy '802.3ad'") as you can see:

/etc/config/network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix '[redacted]'

config device 'switch'
	option name 'switch'
	option type 'bridge'
	option macaddr '[redacted]'
	list ports 'bond-lagg0'
	list ports 'lan1'
	list ports 'lan5'
	list ports 'lan6'
	list ports 'lan7'
	list ports 'lan8'

config bridge-vlan 'lan_vlan'
	option device 'switch'
	option vlan '1'
	list ports 'lan1'
	list ports 'lan5'
	list ports 'lan6'
	list ports 'lan8'

config device
	option name 'switch.1'
	option macaddr '[redacted]'

config interface 'lan'
	option device 'switch.1'
	option proto 'static'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option ipaddr '192.168.8.200'
	option gateway '192.168.8.1'
	list dns '192.168.8.1'
	list dns_search '[redacted]'

config interface 'lagg0'
	option proto 'bonding'
	option force_link '1'
	option ipaddr '10.0.0.1'
	option netmask '255.0.0.0'
	list slaves 'lan2'
	list slaves 'lan3'
	list slaves 'lan4'
	option bonding_policy '802.3ad'
	option min_links '0'
	option ad_actor_sys_prio '65535'
	option ad_select 'stable'
	option lacp_rate 'slow'
	option xmit_hash_policy 'layer2+3'
	option all_slaves_active '0'
	option link_monitoring 'mii'
	option miimon '100'
	option downdelay '0'
	option updelay '0'
	option use_carrier '1'

config bridge-vlan
	option device 'switch'
	option vlan '10'
	list ports 'bond-lagg0:t'
	list ports 'lan7'
	list ports 'lan8:t'

/proc/net/bonding/lagg0

Ethernet Channel Bonding Driver: v5.15.134

Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Peer Notification Delay (ms): 0

Slave Interface: lan2
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:00:00:01:00:00
Slave queue ID: 0

Slave Interface: lan3
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:00:00:01:00:00
Slave queue ID: 0

Slave Interface: lan4
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:00:00:01:00:00
Slave queue ID: 0

ifconfig -a

bond-lagg0 Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:47432 errors:0 dropped:47432 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5217520 (4.9 MiB)  TX bytes:228 (228.0 B)

eth0      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          inet6 addr: [redacted] Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:99000 errors:0 dropped:0 overruns:0 frame:0
          TX packets:52261 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:12675308 (12.0 MiB)  TX bytes:11804417 (11.2 MiB)
          Interrupt:24 Memory:2800000-1b00a3ff 

lan1      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:32521 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32583 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2306395 (2.1 MiB)  TX bytes:2597559 (2.4 MiB)

lan2      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:15811 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1739210 (1.6 MiB)  TX bytes:0 (0.0 B)

lan3      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:15811 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1739210 (1.6 MiB)  TX bytes:94 (94.0 B)

lan4      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:15810 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1739100 (1.6 MiB)  TX bytes:134 (134.0 B)

lan5      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:338 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3854 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:23138 (22.5 KiB)  TX bytes:189226 (184.7 KiB)

lan6      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:18673 errors:0 dropped:23 overruns:0 frame:0
          TX packets:15201 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3343459 (3.1 MiB)  TX bytes:8645493 (8.2 MiB)

lan7      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lan8      Link encap:Ethernet  HWaddr 00:00:00:01:00:00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:36 errors:0 dropped:14 overruns:0 frame:0
          TX packets:605 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2796 (2.7 KiB)  TX bytes:51836 (50.6 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2719 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2719 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:265368 (259.1 KiB)  TX bytes:265368 (259.1 KiB)

switch    Link encap:Ethernet  HWaddr [redacted]  
          inet6 addr: [redacted] Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:51168 errors:0 dropped:0 overruns:0 frame:0
          TX packets:50655 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5632176 (5.3 MiB)  TX bytes:11349738 (10.8 MiB)

switch.1  Link encap:Ethernet  HWaddr [redacted]
          inet addr:192.168.8.200  Bcast:192.168.8.255  Mask:255.255.255.0
          inet6 addr: [redacted] Scope:Link
          inet6 addr: [redacted] Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:51161 errors:0 dropped:0 overruns:0 frame:0
          TX packets:50629 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5631528 (5.3 MiB)  TX bytes:11346522 (10.8 MiB)

/sys/class/net/bond-lagg0/bonding/active_slave
[empty]

/sys/class/net/bond-lagg0/bonding/slave
lan2 lan3 lan4

Reread the whole thread and saw you faced the same problem.
insmod bonding mode=4 gives me module is already loaded and sysctl -a doesn't seem to show me the right parameter to edit.
ip link set dev bond-lagg0 type bond mode 802.3ad is also not working because there are still interfaces enslaved.

So is mode the only parameter I have to change in the bonding module or is there anything else? Mind telling me how I can change this permanently even when there's a new OpenWRT update for my switch?

Actually I just wanted to use the web GUI to set up a simple LAGG and ended playing around with kernel parameters...

I don't think you should have to tinker with insmod in command line, that's the whole point of having the luci interface for link aggregation and this is the mistake I did in the beginning - I followed some old posts that explained that I had to write my own shell script to create the bond interface, when in fact luci was trying to do the same thing and they overlapped and of course it didn't work as it should.

The mode parameter definitely has to be correct though for the link aggregation to work, and if your /proc/net/bonding/lagg0 is showing "Bonding Mode: load balancing (round-robin)" then it's not going to work as long as the other end of the LAG (your OPNsense firewall/router) is set for 802.3ad.

As it happens I also have a Netgear G308T on which I planned to install OpenWrt but unfortunately I really don't have time for this now, at least not this week and the next one. So if I were you I would try to temporarily delete the bond-lagg0 from the luci config and try to create the bond interface from CLI, using insmod with the right mode argument, and watching /proc/net/bonding/lagg0 to see if it's picking it up. If this doesn't work then the problem is not with Luci and therefore it cannot be fixed in Luci. Once you get /proc/net/bonding/lagg0 to show the right LA mode (802.3ad) then you can reboot and start building it again in Luci, as it should work. At least it worked for me! Best of luck!

As I said, these are mandatory. You can set them in CLI (with insmode arguments) OR in Luci. You should not attempt to do this twice though (i.e. both with insmod and Luci) as they will obviously overlap and interfere.

The "option bonding_policy '802.3ad'" that you already have in your Luci configuration should set it for you.

Not sure I understand the "even when there's a new OpenWRT update for my switch" part.

I'm myself a beginner with OpenWrt and Luci so I'm not sure if your vlan config is correct, although you did mention that it used to work before ("Port 8 is my dumb AP which worked great with all VLAN when there was no LAGG") so I reckon it should be correct. I will try to find some time tonight to check your Luci config against mine but unfortunately I can't promise I'll find it (the time).

Hardware offloading if LAGs into the realtek switch fabric has not been implemented for OpenWrt's realtek target/ switch drivers yet. While you can still set up link aggregation in software, this would remain unaccelerated and with abysmal performance (probably around 15 MBit/s, not a typo).

If you need link aggregation for now, you'll either need to stay on the OEM firmware or dive head first into the realtek development.

Wow, thanks, you just saved me from - at some future point in time - replacing the OEM firmware on the Netgear G308T switch with OpenWrt and then wasting a lot of time trying to figure out why the "performance" was so bad!

I suppose the same would happen with a D-Link DGS-1210-16 switch if I replace its OEM firmware with OpenWrt, correct? Apparently it uses the Realtek RTL8382M chip for the switch. Cheers!

Same situation for both switches, both are using the same SOC/ switch fabric. Adding the missing features is realistic, but quite some work (which no one is taking right now).

The mode parameter definitely has to be correct though for the link aggregation to work, and if your /proc/net/bonding/lagg0 is showing "Bonding Mode: load balancing (round-robin)" then it's not going to work as long as the other end of the LAG (your OPNsense firewall/router) is set for 802.3ad.

Yesterday I changed the protocol on my OPNsense also to round robin for testing. So at least I got an IP address via DHCP from it on my test device but could't even ping the interface.

As I said, these are mandatory.

Yes, I set them immediately after you wrote it. I wanted to say that I've tried everything from your list before but hadn't set up the monitoring.

Not sure I understand the "even when there's a new OpenWRT update for my switch" part.

It was just about the kernel paramter. I was looking for a way to set the bonding mode permanently so it won't be ignored when there's a newer version of OpenWrt or kernel.

I'm not sure if your vlan config is correct

I added a new VLAN without the LAGG the day before and everything worked fine. Then I changed in OPNsense the parent interface to my LAGG and everything stopped working again. So it's not my VLAN configuration. Your posts have been very helpful so thanks a last time.

Hardware offloading if LAGs into the realtek switch fabric has not been implemented for OpenWrt's realtek target/ switch drivers yet. While you can still set up link aggregation in software, this would remain unaccelerated and with abysmal performance (probably around 15 MBit/s, not a typo).

Thank you @slh so there's no point in putting any more time into it. I'll reset the switch and use OpenWrt without LAGG for now. In general I hope there will be an easier way to make use of LAGGs in OpenWrt in the future.