From: Rafał Miłecki <ra...@milecki.pl>

The old way of defining bridge (L2) as part of interface (L3) is
deprecated. All such configs should be migrated to define bridge as L3
UCI section type "device".

Signed-off-by: Rafał Miłecki <ra...@milecki.pl>
---
 .../luci-static/resources/tools/network.js    | 388 +++++++-----------
 .../resources/view/network/interfaces.js      |   7 +-
 2 files changed, 147 insertions(+), 248 deletions(-)

diff --git 
a/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js 
b/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js
index 5ed55e24fc..b4d941c60d 100644
--- a/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js
+++ b/modules/luci-mod-network/htdocs/luci-static/resources/tools/network.js
@@ -385,107 +385,41 @@ return baseclass.extend({
        },
 
        addDeviceOptions: function(s, dev, isNew) {
-               var isIface = (s.sectiontype == 'interface'),
-                   ifc = isIface ? network.instantiateNetwork(s.section) : 
null,
-                   gensection = ifc ? 'physical' : 'devgeneral',
-                   advsection = ifc ? 'physical' : 'devadvanced',
-                   simpledep = ifc ? { type: '', ifname_single: /^[^@]/ } : { 
type: '' },
-                   disableLegacyBridging = isIface && 
deviceSectionExists(null, 'br-%s'.format(ifc.getName()), 'bridge'),
-                   o, ss;
-
-               if (isIface) {
-                       if (!s.hasOwnProperty('parse'))
-                               s.parse = sectionParse;
-
-                       var type;
-
-                       /* If an externally configured br-xxx interface already 
exists,
-                        * then disable legacy bridge configuration */
-                       if (disableLegacyBridging) {
-                               type = this.addOption(s, gensection, 
form.HiddenValue, 'type');
-                               type.cfgvalue = function() { return '' };
-                       }
-                       else {
-                               type = this.addOption(s, gensection, form.Flag, 
'type', _('Bridge interfaces'), _('Creates a bridge over specified 
interface(s)'));
-                       }
-
-                       type.modalonly = true;
-                       type.disabled = '';
-                       type.enabled = 'bridge';
-                       type.write = type.remove = function(section_id, value) {
-                               var protoname = 
this.section.formvalue(section_id, 'proto'),
-                                   protocol = network.getProtocol(protoname),
-                                   new_ifnames = this.isActive(section_id) ? 
L.toArray(this.section.formvalue(section_id, value ? 'ifname_multi' : 
'ifname_single')) : [];
-
-                               if (!protocol.isVirtual() && 
!this.isActive(section_id))
-                                       return;
-
-                               var old_ifnames = [],
-                                   devs = ifc.getDevices() || 
L.toArray(ifc.getDevice());
-
-                               for (var i = 0; i < devs.length; i++)
-                                       old_ifnames.push(devs[i].getName());
+               var o, ss;
 
-                               if (!value)
-                                       new_ifnames.length = 
Math.max(new_ifnames.length, 1);
-
-                               old_ifnames.sort();
-                               new_ifnames.sort();
-
-                               for (var i = 0; i < 
Math.max(old_ifnames.length, new_ifnames.length); i++) {
-                                       if (old_ifnames[i] != new_ifnames[i]) {
-                                               // backup_ifnames()
-                                               for (var j = 0; j < 
old_ifnames.length; j++)
-                                                       
ifc.deleteDevice(old_ifnames[j]);
-
-                                               for (var j = 0; j < 
new_ifnames.length; j++)
-                                                       
ifc.addDevice(new_ifnames[j]);
-
-                                               break;
-                                       }
-                               }
+               s.tab('devgeneral', _('General device options'));
+               s.tab('devadvanced', _('Advanced device options'));
+               s.tab('brport', _('Bridge port specific options'));
+               s.tab('bridgevlan', _('Bridge VLAN filtering'));
 
-                               if (value)
-                                       uci.set('network', section_id, 'type', 
'bridge');
-                               else
-                                       uci.unset('network', section_id, 
'type');
-                       };
-               }
-               else {
-                       s.tab('devgeneral', _('General device options'));
-                       s.tab('devadvanced', _('Advanced device options'));
-                       s.tab('brport', _('Bridge port specific options'));
-                       s.tab('bridgevlan', _('Bridge VLAN filtering'));
-
-                       o = this.addOption(s, gensection, form.ListValue, 
'type', _('Device type'));
-                       o.readonly = !isNew;
-                       o.value('', _('Network device'));
-                       o.value('bridge', _('Bridge device'));
-                       o.value('8021q', _('VLAN (802.1q)'));
-                       o.value('8021ad', _('VLAN (802.1ad)'));
-                       o.value('macvlan', _('MAC VLAN'));
-                       o.value('veth', _('Virtual Ethernet'));
-
-                       o = this.addOption(s, gensection, widgets.DeviceSelect, 
'name_simple', _('Existing device'));
-                       o.readonly = !isNew;
-                       o.rmempty = false;
-                       o.noaliases = true;
-                       o.default = (dev ? dev.getName() : '');
-                       o.ucioption = 'name';
-                       o.write = o.remove = setIfActive;
-                       o.filter = function(section_id, value) {
-                               return !deviceSectionExists(section_id, value);
-                       };
-                       o.validate = function(section_id, value) {
-                               return deviceSectionExists(section_id, value) ? 
_('A configuration for the device "%s" already exists').format(value) : true;
-                       };
-                       o.depends('type', '');
-               }
+               o = this.addOption(s, 'devgeneral', form.ListValue, 'type', 
_('Device type'));
+               o.readonly = !isNew;
+               o.value('', _('Network device'));
+               o.value('bridge', _('Bridge device'));
+               o.value('8021q', _('VLAN (802.1q)'));
+               o.value('8021ad', _('VLAN (802.1ad)'));
+               o.value('macvlan', _('MAC VLAN'));
+               o.value('veth', _('Virtual Ethernet'));
+
+               o = this.addOption(s, 'devgeneral', widgets.DeviceSelect, 
'name_simple', _('Existing device'));
+               o.readonly = !isNew;
+               o.rmempty = false;
+               o.noaliases = true;
+               o.default = (dev ? dev.getName() : '');
+               o.ucioption = 'name';
+               o.write = o.remove = setIfActive;
+               o.filter = function(section_id, value) {
+                       return !deviceSectionExists(section_id, value);
+               };
+               o.validate = function(section_id, value) {
+                       return deviceSectionExists(section_id, value) ? _('A 
configuration for the device "%s" already exists').format(value) : true;
+               };
+               o.depends('type', '');
 
-               o = this.addOption(s, gensection, widgets.DeviceSelect, 
'ifname_single', isIface ? _('Interface') : _('Base device'));
+               o = this.addOption(s, 'devgeneral', widgets.DeviceSelect, 
'ifname_single', _('Base device'));
                o.readonly = !isNew;
                o.rmempty = false;
-               o.noaliases = !isIface;
+               o.noaliases = true;
                o.default = (dev ? dev.getName() : '').match(/^.+\.\d+$/) ? 
dev.getName().replace(/\.\d+$/, '') : '';
                o.ucioption = 'ifname';
                o.validate = function(section_id, value) {
@@ -504,29 +438,12 @@ return baseclass.extend({
 
                        return true;
                };
-               if (isIface) {
-                       o.write = o.remove = function() {};
-                       o.cfgvalue = function(section_id) {
-                               return (ifc.getDevices() || 
L.toArray(ifc.getDevice())).map(function(dev) {
-                                       return dev.getName();
-                               });
-                       };
-                       o.onchange = function(ev, section_id, values) {
-                               for (var i = 0, co; (co = 
this.section.children[i]) != null; i++)
-                                       if (co !== this && co.refresh)
-                                               co.refresh(section_id);
-
-                       };
-                       o.depends('type', '');
-               }
-               else {
-                       o.write = o.remove = setIfActive;
-                       o.depends('type', '8021q');
-                       o.depends('type', '8021ad');
-                       o.depends('type', 'macvlan');
-               }
+               o.write = o.remove = setIfActive;
+               o.depends('type', '8021q');
+               o.depends('type', '8021ad');
+               o.depends('type', 'macvlan');
 
-               o = this.addOption(s, gensection, form.Value, 'vid', _('VLAN 
ID'));
+               o = this.addOption(s, 'devgeneral', form.Value, 'vid', _('VLAN 
ID'));
                o.readonly = !isNew;
                o.datatype = 'range(1, 4094)';
                o.rmempty = false;
@@ -546,74 +463,64 @@ return baseclass.extend({
                o.depends('type', '8021q');
                o.depends('type', '8021ad');
 
-               o = this.addOption(s, gensection, form.ListValue, 'mode', 
_('Mode'));
+               o = this.addOption(s, 'devgeneral', form.ListValue, 'mode', 
_('Mode'));
                o.value('vepa', _('VEPA (Virtual Ethernet Port Aggregator)', 
'MACVLAN mode'));
                o.value('private', _('Private (Prevent communication between 
MAC VLANs)', 'MACVLAN mode'));
                o.value('bridge', _('Bridge (Support direct communication 
between MAC VLANs)', 'MACVLAN mode'));
                o.value('passthru', _('Pass-through (Mirror physical device to 
single MAC VLAN)', 'MACVLAN mode'));
                o.depends('type', 'macvlan');
 
-               if (!isIface) {
-                       o = this.addOption(s, gensection, form.Value, 
'name_complex', _('Device name'));
-                       o.rmempty = false;
-                       o.datatype = 'maxlength(15)';
-                       o.readonly = !isNew;
-                       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;
-                       };
-                       o.depends({ type: '', '!reverse': true });
-               }
+               o = this.addOption(s, 'devgeneral', form.Value, 'name_complex', 
_('Device name'));
+               o.rmempty = false;
+               o.datatype = 'maxlength(15)';
+               o.readonly = !isNew;
+               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;
+               };
+               o.depends({ type: '', '!reverse': true });
 
-               o = this.addOption(s, advsection, form.DynamicList, 
'ingress_qos_mapping', _('Ingress QoS mapping'), _('Defines a mapping of VLAN 
header priority to the Linux internal packet priority on incoming frames'));
+               o = this.addOption(s, 'devadvanced', form.DynamicList, 
'ingress_qos_mapping', _('Ingress QoS mapping'), _('Defines a mapping of VLAN 
header priority to the Linux internal packet priority on incoming frames'));
                o.rmempty = true;
                o.validate = validateQoSMap;
                o.depends('type', '8021q');
                o.depends('type', '8021ad');
 
-               o = this.addOption(s, advsection, form.DynamicList, 
'egress_qos_mapping', _('Egress QoS mapping'), _('Defines a mapping of Linux 
internal packet priority to VLAN header priority but for outgoing frames'));
+               o = this.addOption(s, 'devadvanced', form.DynamicList, 
'egress_qos_mapping', _('Egress QoS mapping'), _('Defines a mapping of Linux 
internal packet priority to VLAN header priority but for outgoing frames'));
                o.rmempty = true;
                o.validate = validateQoSMap;
                o.depends('type', '8021q');
                o.depends('type', '8021ad');
 
-               o = this.addOption(s, gensection, widgets.DeviceSelect, 
'ifname_multi', _('Bridge ports'));
+               o = this.addOption(s, 'devgeneral', widgets.DeviceSelect, 
'ifname_multi', _('Bridge ports'));
                o.size = 10;
                o.rmempty = true;
                o.multiple = true;
                o.noaliases = true;
                o.nobridges = true;
                o.ucioption = 'ifname';
-               if (isIface) {
-                       o.write = o.remove = function() {};
-                       o.cfgvalue = function(section_id) {
-                               return (ifc.getDevices() || 
L.toArray(ifc.getDevice())).map(function(dev) { return dev.getName() });
-                       };
-               }
-               else {
-                       o.write = o.remove = setIfActive;
-                       o.default = L.toArray(dev ? dev.getPorts() : 
null).filter(function(p) { return p.getType() != 'wifi' }).map(function(p) { 
return p.getName() });
-                       o.filter = function(section_id, device_name) {
-                               var bridge_name = uci.get('network', 
section_id, 'name'),
-                                   choice_dev = 
network.instantiateDevice(device_name),
-                                   parent_dev = choice_dev.getParent();
-
-                               /* only show wifi networks which are already 
present in "option ifname" */
-                               if (choice_dev.getType() == 'wifi') {
-                                       var ifnames = 
L.toArray(uci.get('network', section_id, 'ifname'));
-
-                                       for (var i = 0; i < ifnames.length; i++)
-                                               if (ifnames[i] == device_name)
-                                                       return true;
-
-                                       return false;
-                               }
+               o.write = o.remove = setIfActive;
+               o.default = L.toArray(dev ? dev.getPorts() : 
null).filter(function(p) { return p.getType() != 'wifi' }).map(function(p) { 
return p.getName() });
+               o.filter = function(section_id, device_name) {
+                       var bridge_name = uci.get('network', section_id, 
'name'),
+                               choice_dev = 
network.instantiateDevice(device_name),
+                               parent_dev = choice_dev.getParent();
+
+                       /* only show wifi networks which are already present in 
"option ifname" */
+                       if (choice_dev.getType() == 'wifi') {
+                               var ifnames = L.toArray(uci.get('network', 
section_id, 'ifname'));
+
+                               for (var i = 0; i < ifnames.length; i++)
+                                       if (ifnames[i] == device_name)
+                                               return true;
+
+                               return false;
+                       }
 
-                               return (!parent_dev || parent_dev.getName() != 
bridge_name);
-                       };
-                       o.description = _('Specifies the wired ports to attach 
to this bridge. In order to attach wireless networks, choose the associated 
interface as network in the wireless settings.')
-               }
+                       return (!parent_dev || parent_dev.getName() != 
bridge_name);
+               };
+               o.description = _('Specifies the wired ports to attach to this 
bridge. In order to attach wireless networks, choose the associated interface 
as network in the wireless settings.')
                o.onchange = function(ev, section_id, values) {
                        ss.updatePorts(values);
 
@@ -623,64 +530,64 @@ return baseclass.extend({
                };
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, gensection, form.Flag, 
'bridge_empty', _('Bring up empty bridge'), _('Bring up the bridge interface 
even if no ports are attached'));
+               o = this.replaceOption(s, 'devgeneral', form.Flag, 
'bridge_empty', _('Bring up empty bridge'), _('Bring up the bridge interface 
even if no ports are attached'));
                o.default = o.disabled;
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Value, 'priority', 
_('Priority'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'priority', _('Priority'));
                o.placeholder = '32767';
                o.datatype = 'range(0, 65535)';
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Value, 
'ageing_time', _('Ageing time'), _('Timeout in seconds for learned MAC 
addresses in the forwarding database'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'ageing_time', _('Ageing time'), _('Timeout in seconds for learned MAC 
addresses in the forwarding database'));
                o.placeholder = '30';
                o.datatype = 'uinteger';
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Flag, 'stp', 
_('Enable <abbr title="Spanning Tree Protocol">STP</abbr>'), _('Enables the 
Spanning Tree Protocol on this bridge'));
+               o = this.replaceOption(s, 'devadvanced', form.Flag, 'stp', 
_('Enable <abbr title="Spanning Tree Protocol">STP</abbr>'), _('Enables the 
Spanning Tree Protocol on this bridge'));
                o.default = o.disabled;
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Value, 'hello_time', 
_('Hello interval'), _('Interval in seconds for STP hello packets'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'hello_time', _('Hello interval'), _('Interval in seconds for STP hello 
packets'));
                o.placeholder = '2';
                o.datatype = 'range(1, 10)';
                o.depends({ type: 'bridge', stp: '1' });
 
-               o = this.replaceOption(s, advsection, form.Value, 
'forward_delay', _('Forward delay'), _('Time in seconds to spend in listening 
and learning states'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'forward_delay', _('Forward delay'), _('Time in seconds to spend in listening 
and learning states'));
                o.placeholder = '15';
                o.datatype = 'range(2, 30)';
                o.depends({ type: 'bridge', stp: '1' });
 
-               o = this.replaceOption(s, advsection, form.Value, 'max_age', 
_('Maximum age'), _('Timeout in seconds until topology updates on link loss'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 'max_age', 
_('Maximum age'), _('Timeout in seconds until topology updates on link loss'));
                o.placeholder = '20';
                o.datatype = 'range(6, 40)';
                o.depends({ type: 'bridge', stp: '1' });
 
 
-               o = this.replaceOption(s, advsection, form.Flag, 
'igmp_snooping', _('Enable <abbr title="Internet Group Management 
Protocol">IGMP</abbr> snooping'), _('Enables IGMP snooping on this bridge'));
+               o = this.replaceOption(s, 'devadvanced', form.Flag, 
'igmp_snooping', _('Enable <abbr title="Internet Group Management 
Protocol">IGMP</abbr> snooping'), _('Enables IGMP snooping on this bridge'));
                o.default = o.disabled;
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Value, 'hash_max', 
_('Maximum snooping table size'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'hash_max', _('Maximum snooping table size'));
                o.placeholder = '512';
                o.datatype = 'uinteger';
                o.depends({ type: 'bridge', igmp_snooping: '1' });
 
-               o = this.replaceOption(s, advsection, form.Flag, 
'multicast_querier', _('Enable multicast querier'));
+               o = this.replaceOption(s, 'devadvanced', form.Flag, 
'multicast_querier', _('Enable multicast querier'));
                o.defaults = { '1': [{'igmp_snooping': '1'}], '0': 
[{'igmp_snooping': '0'}] };
                o.depends('type', 'bridge');
 
-               o = this.replaceOption(s, advsection, form.Value, 'robustness', 
_('Robustness'), _('The robustness value allows tuning for the expected packet 
loss on the network. If a network is expected to be lossy, the robustness value 
may be increased. IGMP is robust to (Robustness-1) packet losses'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'robustness', _('Robustness'), _('The robustness value allows tuning for the 
expected packet loss on the network. If a network is expected to be lossy, the 
robustness value may be increased. IGMP is robust to (Robustness-1) packet 
losses'));
                o.placeholder = '2';
                o.datatype = 'min(1)';
                o.depends({ type: 'bridge', multicast_querier: '1' });
 
-               o = this.replaceOption(s, advsection, form.Value, 
'query_interval', _('Query interval'), _('Interval in centiseconds between 
multicast general queries. By varying the value, an administrator may tune the 
number of IGMP messages on the subnet; larger values cause IGMP Queries to be 
sent less often'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'query_interval', _('Query interval'), _('Interval in centiseconds between 
multicast general queries. By varying the value, an administrator may tune the 
number of IGMP messages on the subnet; larger values cause IGMP Queries to be 
sent less often'));
                o.placeholder = '12500';
                o.datatype = 'uinteger';
                o.depends({ type: 'bridge', multicast_querier: '1' });
 
-               o = this.replaceOption(s, advsection, form.Value, 
'query_response_interval', _('Query response interval'), _('The max response 
time in centiseconds inserted into the periodic general queries. By varying the 
value, an administrator may tune the burstiness of IGMP messages on the subnet; 
larger values make the traffic less bursty, as host responses are spread out 
over a larger interval'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'query_response_interval', _('Query response interval'), _('The max response 
time in centiseconds inserted into the periodic general queries. By varying the 
value, an administrator may tune the burstiness of IGMP messages on the subnet; 
larger values make the traffic less bursty, as host responses are spread out 
over a larger interval'));
                o.placeholder = '1000';
                o.datatype = 'uinteger';
                o.validate = function(section_id, value) {
@@ -694,24 +601,24 @@ return baseclass.extend({
                };
                o.depends({ type: 'bridge', multicast_querier: '1' });
 
-               o = this.replaceOption(s, advsection, form.Value, 
'last_member_interval', _('Last member interval'), _('The max response time in 
centiseconds inserted into group-specific queries sent in response to leave 
group messages. It is also the amount of time between group-specific query 
messages. This value may be tuned to modify the "leave latency" of the network. 
A reduced value results in reduced time to detect the loss of the last member 
of a group'));
+               o = this.replaceOption(s, 'devadvanced', form.Value, 
'last_member_interval', _('Last member interval'), _('The max response time in 
centiseconds inserted into group-specific queries sent in response to leave 
group messages. It is also the amount of time between group-specific query 
messages. This value may be tuned to modify the "leave latency" of the network. 
A reduced value results in reduced time to detect the loss of the last member 
of a group'));
                o.placeholder = '100';
                o.datatype = 'uinteger';
                o.depends({ type: 'bridge', multicast_querier: '1' });
 
-               o = this.addOption(s, gensection, form.Value, 'mtu', _('MTU'));
-               o.placeholder = getDeviceValue(ifc || dev, 'getMTU');
+               o = this.addOption(s, 'devgeneral', form.Value, 'mtu', 
_('MTU'));
+               o.placeholder = getDeviceValue(dev, 'getMTU');
                o.datatype = 'max(9200)';
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, gensection, form.Value, 'macaddr', _('MAC 
address'));
-               o.placeholder = getDeviceValue(ifc || dev, 'getMAC');
+               o = this.addOption(s, 'devgeneral', form.Value, 'macaddr', 
_('MAC address'));
+               o.placeholder = getDeviceValue(dev, 'getMAC');
                o.datatype = 'macaddr';
-               o.depends(simpledep);
+               o.depends('type', '');
                o.depends('type', 'macvlan');
                o.depends('type', 'veth');
 
-               o = this.addOption(s, gensection, form.Value, 'peer_name', 
_('Peer device name'));
+               o = this.addOption(s, 'devgeneral', form.Value, 'peer_name', 
_('Peer device name'));
                o.rmempty = true;
                o.datatype = 'maxlength(15)';
                o.depends('type', 'veth');
@@ -730,21 +637,21 @@ return baseclass.extend({
                        return form.Value.prototype.load.apply(this, arguments);
                };
 
-               o = this.addOption(s, gensection, form.Value, 'peer_macaddr', 
_('Peer MAC address'));
+               o = this.addOption(s, 'devgeneral', form.Value, 'peer_macaddr', 
_('Peer MAC address'));
                o.rmempty = true;
                o.datatype = 'macaddr';
                o.depends('type', 'veth');
 
-               o = this.addOption(s, gensection, form.Value, 'txqueuelen', 
_('TX queue length'));
+               o = this.addOption(s, 'devgeneral', form.Value, 'txqueuelen', 
_('TX queue length'));
                o.placeholder = dev ? dev._devstate('qlen') : '';
                o.datatype = 'uinteger';
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Flag, 'promisc', 
_('Enable promiscious mode'));
+               o = this.addOption(s, 'devadvanced', form.Flag, 'promisc', 
_('Enable promiscious mode'));
                o.default = o.disabled;
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.ListValue, 'rpfilter', 
_('Reverse path filter'));
+               o = this.addOption(s, 'devadvanced', form.ListValue, 
'rpfilter', _('Reverse path filter'));
                o.default = '';
                o.value('', _('disabled'));
                o.value('loose', _('Loose filtering'));
@@ -765,96 +672,96 @@ return baseclass.extend({
                                return '';
                        }
                };
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Flag, 'acceptlocal', 
_('Accept local'), _('Accept packets with local source addresses'));
+               o = this.addOption(s, 'devadvanced', form.Flag, 'acceptlocal', 
_('Accept local'), _('Accept packets with local source addresses'));
                o.default = o.disabled;
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Flag, 'sendredirects', 
_('Send ICMP redirects'));
+               o = this.addOption(s, 'devadvanced', form.Flag, 
'sendredirects', _('Send ICMP redirects'));
                o.default = o.enabled;
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Value, 
'neighreachabletime', _('Neighbour cache validity'), _('Time in milliseconds'));
+               o = this.addOption(s, 'devadvanced', form.Value, 
'neighreachabletime', _('Neighbour cache validity'), _('Time in milliseconds'));
                o.placeholder = '30000';
                o.datatype = 'uinteger';
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Value, 
'neighgcstaletime', _('Stale neighbour cache timeout'), _('Timeout in 
seconds'));
+               o = this.addOption(s, 'devadvanced', form.Value, 
'neighgcstaletime', _('Stale neighbour cache timeout'), _('Timeout in 
seconds'));
                o.placeholder = '60';
                o.datatype = 'uinteger';
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.Value, 'neighlocktime', 
_('Minimum ARP validity time'), _('Minimum required time in seconds before an 
ARP entry may be replaced. Prevents ARP cache thrashing.'));
+               o = this.addOption(s, 'devadvanced', form.Value, 
'neighlocktime', _('Minimum ARP validity time'), _('Minimum required time in 
seconds before an ARP entry may be replaced. Prevents ARP cache thrashing.'));
                o.placeholder = '0';
                o.datatype = 'uinteger';
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, gensection, form.Flag, 'ipv6', _('Enable 
IPv6'));
+               o = this.addOption(s, 'devgeneral', form.Flag, 'ipv6', 
_('Enable IPv6'));
                o.migrate = false;
                o.default = o.enabled;
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, gensection, form.Value, 'mtu6', _('IPv6 
MTU'));
-               o.placeholder = getDeviceValue(ifc || dev, 'getMTU');
+               o = this.addOption(s, 'devgeneral', form.Value, 'mtu6', _('IPv6 
MTU'));
+               o.placeholder = getDeviceValue(dev, 'getMTU');
                o.datatype = 'max(9200)';
-               o.depends(Object.assign({ ipv6: '1' }, simpledep));
+               o.depends(Object.assign({ ipv6: '1' }, 'type', ''));
 
-               o = this.addOption(s, gensection, form.Value, 'dadtransmits', 
_('DAD transmits'), _('Amount of Duplicate Address Detection probes to send'));
+               o = this.addOption(s, 'devgeneral', form.Value, 'dadtransmits', 
_('DAD transmits'), _('Amount of Duplicate Address Detection probes to send'));
                o.placeholder = '1';
                o.datatype = 'uinteger';
-               o.depends(Object.assign({ ipv6: '1' }, simpledep));
+               o.depends(Object.assign({ ipv6: '1' }, 'type', ''));
 
 
-               o = this.addOption(s, advsection, form.Flag, 'multicast', 
_('Enable multicast support'));
+               o = this.addOption(s, 'devadvanced', form.Flag, 'multicast', 
_('Enable multicast support'));
                o.default = o.enabled;
-               o.depends(simpledep);
+               o.depends('type', '');
 
-               o = this.addOption(s, advsection, form.ListValue, 
'igmpversion', _('Force IGMP version'));
+               o = this.addOption(s, 'devadvanced', form.ListValue, 
'igmpversion', _('Force IGMP version'));
                o.value('', _('No enforcement'));
                o.value('1', _('Enforce IGMPv1'));
                o.value('2', _('Enforce IGMPv2'));
                o.value('3', _('Enforce IGMPv3'));
-               o.depends(Object.assign({ multicast: '1' }, simpledep));
+               o.depends(Object.assign({ multicast: '1' }, 'type', ''));
 
-               o = this.addOption(s, advsection, form.ListValue, 'mldversion', 
_('Force MLD version'));
+               o = this.addOption(s, 'devadvanced', form.ListValue, 
'mldversion', _('Force MLD version'));
                o.value('', _('No enforcement'));
                o.value('1', _('Enforce MLD version 1'));
                o.value('2', _('Enforce MLD version 2'));
-               o.depends(Object.assign({ multicast: '1' }, simpledep));
+               o.depends(Object.assign({ multicast: '1' }, 'type', ''));
 
                if (isBridgePort(dev)) {
                        o = this.addOption(s, 'brport', form.Flag, 'learning', 
_('Enable MAC address learning'));
                        o.default = o.enabled;
-                       o.depends(simpledep);
+                       o.depends('type', '');
 
                        o = this.addOption(s, 'brport', form.Flag, 
'unicast_flood', _('Enable unicast flooding'));
                        o.default = o.enabled;
-                       o.depends(simpledep);
+                       o.depends('type', '');
 
                        o = this.addOption(s, 'brport', form.Flag, 'isolated', 
_('Port isolation'), _('Only allow communication with non-isolated bridge ports 
when enabled'));
                        o.default = o.disabled;
-                       o.depends(simpledep);
+                       o.depends('type', '');
 
                        o = this.addOption(s, 'brport', form.ListValue, 
'multicast_router', _('Multicast routing'));
                        o.value('', _('Never'));
                        o.value('1', _('Learn'));
                        o.value('2', _('Always'));
-                       o.depends(Object.assign({ multicast: '1' }, simpledep));
+                       o.depends(Object.assign({ multicast: '1' }, 'type', 
''));
 
                        o = this.addOption(s, 'brport', form.Flag, 
'multicast_to_unicast', _('Multicast to unicast'), _('Forward multicast packets 
as unicast packets on this device.'));
                        o.default = o.disabled;
-                       o.depends(Object.assign({ multicast: '1' }, simpledep));
+                       o.depends(Object.assign({ multicast: '1' }, 'type', 
''));
 
                        o = this.addOption(s, 'brport', form.Flag, 
'multicast_fast_leave', _('Enable multicast fast leave'));
                        o.default = o.disabled;
-                       o.depends(Object.assign({ multicast: '1' }, simpledep));
+                       o.depends(Object.assign({ multicast: '1' }, 'type', 
''));
                }
 
                o = this.addOption(s, 'bridgevlan', form.Flag, 
'vlan_filtering', _('Enable VLAN filterering'));
                o.depends('type', 'bridge');
                o.updateDefaultValue = function(section_id) {
-                       var device = isIface ? 'br-%s'.format(s.section) : 
uci.get('network', s.section, 'name'),
+                       var device = uci.get('network', s.section, 'name'),
                            uielem = this.getUIElement(section_id),
                            has_vlans = false;
 
@@ -896,7 +803,7 @@ return baseclass.extend({
                };
 
                ss.filter = function(section_id) {
-                       var devname = isIface ? 'br-%s'.format(s.section) : 
uci.get('network', s.section, 'name');
+                       var devname = uci.get('network', s.section, 'name');
                        return (uci.get('network', section_id, 'device') == 
devname);
                };
 
@@ -943,7 +850,7 @@ return baseclass.extend({
 
                ss.handleAdd = function(ev) {
                        return s.parse().then(L.bind(function() {
-                               var device = isIface ? 
'br-%s'.format(s.section) : uci.get('network', s.section, 'name'),
+                               var device = uci.get('network', s.section, 
'name'),
                                    section_ids = this.cfgsections(),
                                    section_id = null,
                                    max_vlan_id = 0;
@@ -1007,38 +914,25 @@ return baseclass.extend({
                o = ss.option(form.Flag, 'local', _('Local'));
                o.default = o.enabled;
 
-               /* Do not touch bridge port state from interface config if 
legacy
-                * bridge config is disabled due to explicitely declared br-xxx
-                * device section... */
-               if (disableLegacyBridging)
-                       return;
-
                var ports = [];
 
-               if (isIface) {
-                       Array.prototype.push.apply(ports, 
L.toArray(ifc.getDevices() || ifc.getDevice()).map(function(dev) {
-                               return dev.getName();
-                       }));
-               }
-               else {
-                       var seen_ports = {};
+               var seen_ports = {};
 
-                       L.toArray(uci.get('network', s.section, 
'ifname')).forEach(function(ifname) {
-                               seen_ports[ifname] = true;
-                       });
+               L.toArray(uci.get('network', s.section, 
'ifname')).forEach(function(ifname) {
+                       seen_ports[ifname] = true;
+               });
 
-                       uci.sections('network', 'bridge-vlan', function(bvs) {
-                               L.toArray(bvs.ports).forEach(function(portspec) 
{
-                                       var m = 
portspec.match(/^([^:]+)(?::[ut*]+)?$/);
+               uci.sections('network', 'bridge-vlan', function(bvs) {
+                       L.toArray(bvs.ports).forEach(function(portspec) {
+                               var m = portspec.match(/^([^:]+)(?::[ut*]+)?$/);
 
-                                       if (m)
-                                               seen_ports[m[1]] = true;
-                               });
+                               if (m)
+                                       seen_ports[m[1]] = true;
                        });
+               });
 
-                       for (var port_name in seen_ports)
-                               ports.push(port_name);
-               }
+               for (var port_name in seen_ports)
+                       ports.push(port_name);
 
                ports.sort();
 
diff --git 
a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js
 
b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js
index a707fcf954..6eebb09e9d 100644
--- 
a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js
+++ 
b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js
@@ -420,6 +420,12 @@ return view.extend({
                                                
.then(L.bind(this.renderMoreOptionsModal, this, s.section));
                                }, this);
 
+                               o = s.taboption('general', 
widgets.DeviceSelect, 'ifname', _('Interface'));
+                               o.nobridges = false;
+                               o.noaliases = false;
+                               o.optional = false;
+                               o.network = ifc.getName();
+
                                o = s.taboption('general', form.Flag, 'auto', 
_('Bring up on boot'));
                                o.modalonly = true;
                                o.default = o.enabled;
@@ -677,7 +683,6 @@ return view.extend({
                                }
 
                                ifc.renderFormOptions(s);
-                               nettools.addDeviceOptions(s, null, true);
 
                                // Common interface options
                                o = nettools.replaceOption(s, 'advanced', 
form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no 
default route is configured'));
-- 
2.26.2


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to