Normally, handling network packets (routing, NAT, …) is done by the Linux kernel on the CPU.
Hauke is a SW engineer in Intel’s connected home division and active in OpenWRT.
Doing network handling on the CPU is very flexible, but with high-speed connections it puts a lot of load on the CPU. The hardware provides offloading possibilities: L2 switching, multicast forwarding, VLAN translation; L3 NAT, static routes, PPP.
For L2, OpenWRT already has offloading support in swconfig. However, this never went upstream to the kernel. Upstream instead has two subsystems: DSA and switchdev. Big differences are that upstream allows to use the normal networking tools (ip, brctl) and there is one network device per port. OpenWRT supports the upstream systems as well.
Compared to switchdev, DSA offers more abstraction: for each feature there is a driver callback; if the driver doesn’t implement it, the normal software implementation is used. In the model, there is one ethernet controller connecting to the CPU and the switch is an additional device of which one port connects to the CPU. It supports bridge offloading, static flow configuration, multicast flow configuration (where the IGMP snooping is still done in the Linux software bridge), port mirroring. It is called Distributed because it supports multiple chips composing a switch.
For L3, every vendor has their own drivers, kernel hacks and tools. About a year ago there was some effort to push flow offloading into the upstream kernel, merged in 4.16 and backported to 4.14 by OpenWRT.
Flow offloading will still do the complicated things (slow path) in the Linux networking stack, the simple things are offloaded: normal forwarding and NAT. Flows are detected and built up with netfilter conntrack. It probably doesn’t support all the features that vendor hacks have, but it’s a good start.
When a packet is received, it is checked if the flow is known. If not, it is forwarded to the Linux networking stack. If it is known, the NAT translation (if any) is applied and it is forwarded to the correct port. This is software flow offloading. For hardware offloading, when a flow is constructed, the driver implements a callback to send it to hardware. If the hardware supports it, it is added there, otherwise it is added to the software flow table. Hardware offloading is not upstream yet because there is no driver using it yet. In OpenWRT, the flow offloading is extended to support bridges, VLANs and PPPoE.
So finally there is something upstream (in Linux and in OpenWRT). In the future, hopefully more can go into the mainline. Another future step is to get QoS in flow offloading.