Do not restrict lower device resolving to hardware flow offloading, it is
required for software flow offloading as well.
While we're at it, also refactor and simplify the code to not require ubus
runtime state for device resolving anymore.
Fixes: #9854
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-function resolve_lower_devices(devstatus, devname) {
- let dir = fs.opendir(`/sys/class/net/${devname}`);
- let devs = [];
+function determine_device_type(devname) {
+ let uevent = fs.open(`/sys/class/net/${devname}/uevent`),
+ devtype = null;
- if (dir) {
- if (!devstatus || devstatus[devname]?.["hw-tc-offload"]) {
- push(devs, devname);
+ if (uevent) {
+ let line;
+
+ while ((line = uevent.read('line')) != null) {
+ let m = match(line, /^DEVTYPE=(\w+)/);
+
+ if (m) {
+ devtype = m[1];
+ break;
+ }
+
+ uevent.close();
+ }
+
+ return devtype;
+}
+
+function resolve_lower_devices(devname) {
+ switch (determine_device_type(devname)) {
+ case null:
+ return [];
+
+ case 'vlan':
+ case 'bridge':
+ let dir = fs.opendir(`/sys/class/net/${devname}`);
+ let lower = [];
+
+ if (dir) {
let e;
while ((e = dir.read()) != null)
if (index(e, "lower_") === 0)
let e;
while ((e = dir.read()) != null)
if (index(e, "lower_") === 0)
- push(devs, ...resolve_lower_devices(devstatus, substr(e, 6)));
+ push(lower, ...resolve_lower_devices(substr(e, 6)));
+
+ dir.close();
+ default:
+ return [ devname ];
+ }
}
function nft_json_command(...args) {
}
function nft_json_command(...args) {
},
resolve_offload_devices: function() {
},
resolve_offload_devices: function() {
- if (!this.default_option("flow_offloading"))
- return [];
-
- let devstatus = null;
- if (this.default_option("flow_offloading_hw")) {
- let bus = ubus.connect();
-
- if (bus) {
- devstatus = bus.call("network.device", "status") || {};
- bus.disconnect();
- }
-
+ if (this.default_option("flow_offloading")) {
for (let zone in this.zones())
for (let device in zone.related_physdevs)
for (let zone in this.zones())
for (let device in zone.related_physdevs)
- push(devices, ...resolve_lower_devices(devstatus, device));
-
- devices = uniq(devices);
-
- if (nft_try_hw_offload(devices))
- return devices;
+ push(devices, ...resolve_lower_devices(device));
- this.warn('Hardware flow offloading unavailable, falling back to software offloading');
- this.state.defaults.flow_offloading_hw = false;
+ if (length(devices)) {
+ devices = sort(uniq(devices));
+ if (this.default_option("flow_offloading_hw") && !nft_try_hw_offload(devices)) {
+ this.warn('Hardware flow offloading unavailable, falling back to software offloading');
+ this.state.defaults.flow_offloading_hw = false;
+ }
+ }
- for (let zone in this.zones())
- for (let device in zone.match_devices)
- push(devices, ...resolve_lower_devices(null, device));
-
- return uniq(devices);
},
check_set_types: function() {
},
check_set_types: function() {
[!] Section @defaults[0] specifies unknown option 'unknown_defaults_option'
[!] Section @rule[9] (Test-Deprecated-Rule-Option) option '_name' is deprecated by fw4
[!] Section @rule[9] (Test-Deprecated-Rule-Option) specifies unknown option 'unknown_rule_option'
[!] Section @defaults[0] specifies unknown option 'unknown_defaults_option'
[!] Section @rule[9] (Test-Deprecated-Rule-Option) option '_name' is deprecated by fw4
[!] Section @rule[9] (Test-Deprecated-Rule-Option) specifies unknown option 'unknown_rule_option'
-[call] ctx.call object <network.device> method <status> args <null>
+[call] fs.open path </sys/class/net/br-lan/uevent> mode <null>
[call] fs.opendir path </sys/class/net/br-lan>
[call] fs.opendir path </sys/class/net/br-lan>
-[call] fs.opendir path </sys/class/net/eth0>
-[call] fs.opendir path </sys/class/net/eth1>
+[call] fs.open path </sys/class/net/eth0/uevent> mode <null>
+[call] fs.open path </sys/class/net/eth1/uevent> mode <null>
[call] system command </usr/sbin/nft -c '
add table inet fw4-hw-offload-test;
add flowtable inet fw4-hw-offload-test ft {
[call] system command </usr/sbin/nft -c '
add table inet fw4-hw-offload-test;
add flowtable inet fw4-hw-offload-test ft {