luci-mod-network: allow device declarations and device configs to coexist
authorJo-Philipp Wich <[email protected]>
Sat, 5 Jun 2021 16:41:39 +0000 (18:41 +0200)
committerJo-Philipp Wich <[email protected]>
Sat, 5 Jun 2021 16:41:39 +0000 (18:41 +0200)
It is legal to have two device sections referring to the same netdev if one
section is a declaration (a section setting option type) and the other is
a configuration (a section not specifying a type but matching an existing
netdev).

Support this case in LuCI since it might be required for some complex
device setups.

Additionally, fix the device type determination for device configuration
sections without type, those should be treated as ethernet (a.k.a.
simple device) configuration instead of falling back to the underlying
netdev device type.

Signed-off-by: Jo-Philipp Wich <[email protected]>
modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js
modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js

index 80b4b2b34308ec6abfd2d1b492536e361eb50f79..d008feb56af75881831d0d84e53a1a5c601fc49b 100644 (file)
@@ -46,11 +46,15 @@ function validateQoSMap(section_id, value) {
        return true;
 }
 
-function deviceSectionExists(section_id, devname, devtype) {
+function deviceSectionExists(section_id, devname, ignore_type_match) {
        var exists = false;
 
        uci.sections('network', 'device', function(ss) {
-               exists = exists || (ss['.name'] != section_id && ss.name == devname && (!devtype || devtype == ss.type));
+               exists = exists || (
+                       ss['.name'] != section_id &&
+                       ss.name == devname &&
+                       (!ignore_type_match || !ignore_type_match.test(ss.type || ''))
+               );
        });
 
        return exists;
@@ -409,10 +413,11 @@ return baseclass.extend({
                o.ucioption = 'name';
                o.write = o.remove = setIfActive;
                o.filter = function(section_id, value) {
-                       return !deviceSectionExists(section_id, value);
+                       return !deviceSectionExists(section_id, value, /^(?:bridge|8021q|8021ad|macvlan|veth)$/);
                };
                o.validate = function(section_id, value) {
-                       return deviceSectionExists(section_id, value) ? _('A configuration for the device "%s" already exists').format(value) : true;
+                       return deviceSectionExists(section_id, value, /^(?:bridge|8021q|8021ad|macvlan|veth)$/)
+                               ? _('A configuration for the device "%s" already exists').format(value) : true;
                };
                o.depends('type', '');
 
@@ -479,7 +484,7 @@ return baseclass.extend({
                o.ucioption = 'name';
                o.write = o.remove = setIfActive;
                o.validate = function(section_id, value) {
-                       return deviceSectionExists(section_id, value) ? _('The device name "%s" is already taken').format(value) : true;
+                       return deviceSectionExists(section_id, value, /^$/) ? _('The device name "%s" is already taken').format(value) : true;
                };
                o.depends({ type: '', '!reverse': true });
 
index ee946f836ee5219d630123311209ab1f427e6779..544cad1aa152f655dea353e4a236c67973b5bfb9 100644 (file)
@@ -1191,10 +1191,11 @@ return view.extend({
                }
 
                function getDevType(section_id) {
-                       var cfgtype = uci.get('network', section_id, 'type'),
-                           dev = getDevice(section_id);
+                       var dev = getDevice(section_id),
+                           cfg = uci.get('network', section_id),
+                           type = cfg ? (uci.get('network', section_id, 'type') || 'ethernet') : (dev ? dev.getType() : '');
 
-                       switch (cfgtype || (dev ? dev.getType() : '')) {
+                       switch (type) {
                        case '':
                                return null;