diff --git a/modules/luci-base/htdocs/luci-static/resources/network.js b/modules/luci-base/htdocs/luci-static/resources/network.js index d71aa69fa361..79191603f1ac 100644 --- a/modules/luci-base/htdocs/luci-static/resources/network.js +++ b/modules/luci-base/htdocs/luci-static/resources/network.js @@ -639,7 +639,7 @@ function enumerateNetworks() { } -var Hosts, Network, Protocol, Device, WifiDevice, WifiNetwork; +var Hosts, Network, Protocol, Device, WifiDevice, WifiNetwork, WifiVlan; /** * @class network @@ -4150,16 +4150,42 @@ WifiNetwork = baseclass.extend(/** @lends LuCI.network.WifiNetwork.prototype */ */ getAssocList: function() { var tasks = []; - var ifnames = [ this.getIfname() ].concat(this.getVlanIfnames()); + var station; - for (var i = 0; i < ifnames.length; i++) - tasks.push(callIwinfoAssoclist(ifnames[i])); + for (let vlan of this.getVlans()) + tasks.push(callIwinfoAssoclist(vlan.getIfname()).then( + function(stations) { + for (station of stations) + station.vlan = vlan; + + return stations; + }) + ); + + tasks.push(callIwinfoAssoclist(this.getIfname())); return Promise.all(tasks).then(function(values) { return Array.prototype.concat.apply([], values); }); }, + /** + * Fetch the vlans for this network. + * + * @returns {Array} + * Returns an array of vlans for this network. + */ + getVlans: function() { + var vlans = []; + var vlans_ubus = this.ubus('net', 'vlans'); + + if (vlans_ubus) + for (let vlan of vlans_ubus) + vlans.push(new WifiVlan(vlan)); + + return vlans; + }, + /** * Query the current operating frequency of the wireless network. * @@ -4436,4 +4462,77 @@ WifiNetwork = baseclass.extend(/** @lends LuCI.network.WifiNetwork.prototype */ } }); +/** + * @class + * @memberof LuCI.network + * @hideconstructor + * @classdesc + * + * A `Network.WifiVlan` class instance represents a vlan on a WifiNetwork. + */ +WifiVlan = baseclass.extend(/** @lends LuCI.network.WifiVlan.prototype */ { + __init__: function(vlan) { + this.ifname = vlan.ifname; + if (L.isObject(vlan.config)) { + this.vid = vlan.config.vid; + this.name = vlan.config.name; + + if (Array.isArray(vlan.config.network) && vlan.config.network.length) + this.network = vlan.config.network[0]; + } + }, + + /** + * Get the name of the wifi vlan. + * + * @returns {string} + * Returns the name. + */ + getName: function() { + return this.name; + }, + + /** + * Get the vlan id of the wifi vlan. + * + * @returns {number} + * Returns the vlan id. + */ + getVlanId: function() { + return this.vid; + }, + + /** + * Get the network of the wifi vlan. + * + * @returns {string} + * Returns the network. + */ + getNetwork: function() { + return this.network; + }, + + /** + * Get the Linux network device name of the wifi vlan. + * + * @returns {string} + * Returns the current network device name for this wifi vlan. + */ + getIfname: function() { + return this.ifname; + }, + + /** + * Get a long description string for the wifi vlan. + * + * @returns {string} + * Returns a string containing the vlan id and the vlan name, + * if it is different than the vlan id + */ + getI18n: function() { + var name = this.name && this.name != this.vid ? ' (' + this.name + ')' : ''; + return 'vlan %d%s'.format(this.vid, name); + }, +}); + return Network; diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js index 4b12042b721c..64dad5cfbcbb 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js @@ -765,6 +765,25 @@ return view.extend({ ]) ]; + var zones = data[4]; + if (bss.vlan) { + var desc = bss.vlan.getI18n(); + var vlan_network = bss.vlan.getNetwork(); + var vlan_zone; + + if (vlan_network && zones) + for (let zone of zones) + if (zone.getNetworks().includes(vlan_network)) + vlan_zone = zone; + + row[0].insertBefore( + E('div', { + 'class' : 'zonebadge', + 'title' : desc, + 'style' : firewall.getZoneColorStyle(vlan_zone) + }, [ desc ]), row[0].firstChild); + } + if (bss.network.isClientDisconnectSupported()) { if (table.firstElementChild.childNodes.length < 6) table.firstElementChild.appendChild(E('th', { 'class': 'th cbi-section-actions'})); @@ -803,7 +822,8 @@ return view.extend({ return Promise.all([ uci.changes(), uci.load('wireless'), - uci.load('system') + uci.load('system'), + firewall.getZones(), ]); }, @@ -823,11 +843,11 @@ return view.extend({ params: [ 'config', 'section', 'name' ] }), - render: function() { + render: function(data) { if (this.checkAnonymousSections()) return this.renderMigration(); else - return this.renderOverview(); + return this.renderOverview(data[3]); }, handleMigration: function(ev) { @@ -862,7 +882,7 @@ return view.extend({ ]); }, - renderOverview: function() { + renderOverview: function(zones) { var m, s, o; m = new form.Map('wireless'); @@ -2402,6 +2422,10 @@ return view.extend({ return hosts_radios_wifis; }); }, network)) + .then(L.bind(function(zones, data) { + data.push(zones); + return data; + }, network, zones)) .then(L.bind(this.poll_status, this, nodes)); }, this), 5); diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js index 805423053076..c77e88fb76f3 100644 --- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js +++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js @@ -5,6 +5,7 @@ 'require uci'; 'require fs'; 'require rpc'; +'require firewall'; return baseclass.extend({ title: _('Wireless'), @@ -184,6 +185,7 @@ return baseclass.extend({ network.getHostHints(), this.callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'read'), this.callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'write'), + firewall.getZones(), L.hasSystemFeature('wifi') ? L.resolveDefault(uci.load('wireless')) : L.resolveDefault(), ]).then(L.bind(function(data) { var tasks = [], @@ -216,7 +218,8 @@ return baseclass.extend({ networks = data[1], hosthints = data[2], hasReadPermission = data[3], - hasWritePermission = data[4]; + hasWritePermission = data[4], + zones = data[5]; var table = E('div', { 'class': 'network-status-table' }); @@ -326,6 +329,24 @@ return baseclass.extend({ ]) ]; + if (bss.vlan) { + var desc = bss.vlan.getI18n(); + var vlan_network = bss.vlan.getNetwork(); + var vlan_zone; + + if (vlan_network) + for (let zone of zones) + if (zone.getNetworks().includes(vlan_network)) + vlan_zone = zone; + + row[0].insertBefore( + E('div', { + 'class' : 'zonebadge', + 'title' : desc, + 'style' : firewall.getZoneColorStyle(vlan_zone) + }, [ desc ]), row[0].firstChild); + } + if (networks[i].isClientDisconnectSupported() && hasWritePermission) { if (assoclist.firstElementChild.childNodes.length < 6) assoclist.firstElementChild.appendChild(E('th', { 'class': 'th cbi-section-actions' }));