luci-mod-network: allow device declarations and device configs to coexist

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 <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2021-06-05 18:41:39 +02:00
parent 3c6b59504a
commit a6c0ad00b2
2 changed files with 14 additions and 8 deletions

View 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 });

View 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;