luci-base: network.js: consider uci config for Device.getType()/getParent()
authorJo-Philipp Wich <jo@mein.io>
Thu, 16 Jun 2022 07:47:47 +0000 (09:47 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 16 Jun 2022 07:52:36 +0000 (09:52 +0200)
For network devices declared in uci but not yet created by netifd, the
runtime status information will be unavailable, causing methods such as
`getType()` to assume plain ethernet interfaces and `getParent()` to fail
resolving parent devices.

Fall back to infer the information from uci configuration settings in such
cases to give accurate type hints to callers.

In particular, this prevents LuCI from turning wireless target networks
containing a to-be-created bridge device into bridges themselves.

Fixes: https://github.com/openwrt/packages/issues/18768
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/network.js

index 8c9ee255ff0ecc84ed2cb67b9ff256f62dae535e..864cbba52c900c48f0acee6fef2414fbee649992 100644 (file)
@@ -2852,6 +2852,15 @@ Device = baseclass.extend(/** @lends LuCI.network.Device.prototype */ {
                this.device  = this.device || device;
                this.dev     = Object.assign({}, _state.netdevs[this.device]);
                this.network = network;
+
+               var conf;
+
+               uci.sections('network', 'device', function(s) {
+                       if (s.name == device)
+                               conf = s;
+               });
+
+               this.config  = Object.assign({}, conf);
        },
 
        _devstate: function(/* ... */) {
@@ -2946,6 +2955,10 @@ Device = baseclass.extend(/** @lends LuCI.network.Device.prototype */ {
                        return 'vlan';
                else if (this.dev.devtype == 'dsa' || _state.isSwitch[this.device])
                        return 'switch';
+               else if (this.config.type == '8021q' || this.config.type == '8021ad')
+                       return 'vlan';
+               else if (this.config.type == 'bridge')
+                       return 'bridge';
                else
                        return 'ethernet';
        },
@@ -3245,7 +3258,13 @@ Device = baseclass.extend(/** @lends LuCI.network.Device.prototype */ {
         * ordinary ethernet interfaces.
         */
        getParent: function() {
-               return this.dev.parent ? Network.prototype.instantiateDevice(this.dev.parent) : null;
+               if (this.dev.parent)
+                       return Network.prototype.instantiateDevice(this.dev.parent);
+
+               if ((this.config.type == '8021q' || this.config.type == '802ad') && typeof(this.config.ifname) == 'string')
+                       return Network.prototype.instantiateDevice(this.config.ifname);
+
+               return null;
        }
 });