From 5e1751397daabcf3c09d455d6e9bef5029e388e6 Mon Sep 17 00:00:00 2001 From: sbwml Date: Wed, 12 Jul 2023 02:16:52 +0800 Subject: [PATCH] Revert "update 29_ethinfo.js from imm" This reverts commit 9dcb4118811d6beea257ee976cbf7e8d91c1f0e7. --- files/generic/29_ethinfo.js | 367 ++------------------ files/generic/luci-mod-status-autocore.json | 3 +- 2 files changed, 39 insertions(+), 331 deletions(-) diff --git a/files/generic/29_ethinfo.js b/files/generic/29_ethinfo.js index 69bf6cb..fa89c4a 100644 --- a/files/generic/29_ethinfo.js +++ b/files/generic/29_ethinfo.js @@ -1,351 +1,60 @@ 'use strict'; 'require baseclass'; -'require fs'; -'require ui'; -'require uci'; 'require rpc'; -'require network'; -'require firewall'; -var callNetworkStatus = rpc.declare({ - object: 'network.device', - method: 'status', +var callLuciETHInfo = rpc.declare({ + object: 'luci', + method: 'getETHInfo', expect: { '': {} } }); - -function isString(v) -{ - return typeof(v) === 'string' && v !== ''; -} - -function resolveVLANChain(ifname, bridges, mapping) -{ - while (!mapping[ifname]) { - var m = ifname.match(/^(.+)\.([^.]+)$/); - - if (!m) - break; - - if (bridges[m[1]]) { - if (bridges[m[1]].vlan_filtering) - mapping[ifname] = bridges[m[1]].vlans[m[2]]; - else - mapping[ifname] = bridges[m[1]].ports; - } - else if (/^[0-9]{1,4}$/.test(m[2]) && m[2] <= 4095) { - mapping[ifname] = [ m[1] ]; - } - else { - break; - } - - ifname = m[1]; - } -} - -function buildVLANMappings(mapping) -{ - var bridge_vlans = uci.sections('network', 'bridge-vlan'), - vlan_devices = uci.sections('network', 'device'), - interfaces = uci.sections('network', 'interface'), - bridges = {}; - - /* find bridge VLANs */ - for (var i = 0, s; (s = bridge_vlans[i]) != null; i++) { - if (!isString(s.device) || !/^[0-9]{1,4}$/.test(s.vlan) || +s.vlan > 4095) - continue; - - var aliases = L.toArray(s.alias), - ports = L.toArray(s.ports), - br = bridges[s.device] = (bridges[s.device] || { ports: [], vlans: {}, vlan_filtering: true }); - - br.vlans[s.vlan] = []; - - for (var j = 0; j < ports.length; j++) { - var port = ports[j].replace(/:[ut*]+$/, ''); - - if (br.ports.indexOf(port) === -1) - br.ports.push(port); - - br.vlans[s.vlan].push(port); - } - - for (var j = 0; j < aliases.length; j++) - if (aliases[j] != s.vlan) - br.vlans[aliases[j]] = br.vlans[s.vlan]; - } - - /* find bridges, VLAN devices */ - for (var i = 0, s; (s = vlan_devices[i]) != null; i++) { - if (s.type == 'bridge') { - if (!isString(s.name)) - continue; - - var ports = L.toArray(s.ports), - br = bridges[s.name] || (bridges[s.name] = { ports: [], vlans: {}, vlan_filtering: false }); - - if (s.vlan_filtering == '0') - br.vlan_filtering = false; - else if (s.vlan_filtering == '1') - br.vlan_filtering = true; - - for (var j = 0; j < ports.length; j++) - if (br.ports.indexOf(ports[j]) === -1) - br.ports.push(ports[j]); - - mapping[s.name] = br.ports; - } - else if (s.type == '8021q' || s.type == '8021ad') { - if (!isString(s.name) || !isString(s.vid) || !isString(s.ifname)) - continue; - - /* parent device is a bridge */ - if (bridges[s.ifname]) { - /* parent bridge is VLAN enabled, device refers to VLAN ports */ - if (bridges[s.ifname].vlan_filtering) - mapping[s.name] = bridges[s.ifname].vlans[s.vid]; - - /* parent bridge is not VLAN enabled, device refers to all bridge ports */ - else - mapping[s.name] = bridges[s.ifname].ports; - } - - /* parent is a simple netdev */ - else { - mapping[s.name] = [ s.ifname ]; - } - - resolveVLANChain(s.ifname, bridges, mapping); - } - } - - /* resolve VLAN tagged interfaces in bridge ports */ - for (var brname in bridges) { - for (var i = 0; i < bridges[brname].ports.length; i++) - resolveVLANChain(bridges[brname].ports[i], bridges, mapping); - - for (var vid in bridges[brname].vlans) - for (var i = 0; i < bridges[brname].vlans[vid].length; i++) - resolveVLANChain(bridges[brname].vlans[vid][i], bridges, mapping); - } - - /* find implicit VLAN devices */ - for (var i = 0, s; (s = interfaces[i]) != null; i++) { - if (!isString(s.device)) - continue; - - resolveVLANChain(s.device, bridges, mapping); - } -} - -function resolveVLANPorts(ifname, mapping) -{ - var ports = []; - - if (mapping[ifname]) - for (var i = 0; i < mapping[ifname].length; i++) - ports.push.apply(ports, resolveVLANPorts(mapping[ifname][i], mapping)); - else - ports.push(ifname); - - return ports.sort(L.naturalCompare); -} - -function buildInterfaceMapping(zones, networks) { - var vlanmap = {}, - portmap = {}, - netmap = {}; - - buildVLANMappings(vlanmap); - - for (var i = 0; i < networks.length; i++) { - var l3dev = networks[i].getDevice(); - - if (!l3dev) - continue; - - var ports = resolveVLANPorts(l3dev.getName(), vlanmap); - - for (var j = 0; j < ports.length; j++) { - portmap[ports[j]] = portmap[ports[j]] || { networks: [], zones: [] }; - portmap[ports[j]].networks.push(networks[i]); - } - - netmap[networks[i].getName()] = networks[i]; - } - - for (var i = 0; i < zones.length; i++) { - var networknames = zones[i].getNetworks(); - - for (var j = 0; j < networknames.length; j++) { - if (!netmap[networknames[j]]) - continue; - - var l3dev = netmap[networknames[j]].getDevice(); - - if (!l3dev) - continue; - - var ports = resolveVLANPorts(l3dev.getName(), vlanmap); - - for (var k = 0; k < ports.length; k++) { - portmap[ports[k]] = portmap[ports[k]] || { networks: [], zones: [] }; - - if (portmap[ports[k]].zones.indexOf(zones[i]) === -1) - portmap[ports[k]].zones.push(zones[i]); - } - } - } - - return portmap; -} - -function formatSpeed(speed, duplex) { - if (speed && duplex) { - var d = (duplex == 'half') ? '\u202f(H)' : '', - e = E('span', { 'title': _('Speed: %d Mbit/s, Duplex: %s').format(speed, duplex) }); - - switch (speed) { - case 10: e.innerText = '10\u202fM' + d; break; - case 100: e.innerText = '100\u202fM' + d; break; - case 1000: e.innerText = '1\u202fGbE' + d; break; - case 2500: e.innerText = '2.5\u202fGbE'; break; - case 5000: e.innerText = '5\u202fGbE'; break; - case 10000: e.innerText = '10\u202fGbE'; break; - case 25000: e.innerText = '25\u202fGbE'; break; - case 40000: e.innerText = '40\u202fGbE'; break; - default: e.innerText = '%d\u202fMbE%s'.format(speed, d); - } - - return e; - } - - return _('no link'); -} - -function formatStats(portdev) { - var stats = portdev._devstate('stats'); - - return ui.itemlist(E('span'), [ - _('Received bytes'), '%1024mB'.format(stats.rx_bytes), - _('Received packets'), '%1000mPkts.'.format(stats.rx_packets), - _('Received multicast'), '%1000mPkts.'.format(stats.multicast), - _('Receive errors'), '%1000mPkts.'.format(stats.rx_errors), - _('Receive dropped'), '%1000mPkts.'.format(stats.rx_dropped), - - _('Transmitted bytes'), '%1024mB'.format(stats.tx_bytes), - _('Transmitted packets'), '%1000mPkts.'.format(stats.tx_packets), - _('Transmit errors'), '%1000mPkts.'.format(stats.tx_errors), - _('Transmit dropped'), '%1000mPkts.'.format(stats.tx_dropped), - - _('Collisions seen'), stats.collisions - ]); -} - -function renderNetworkBadge(network, zonename) { - var l3dev = network.getDevice(); - var span = E('span', { 'class': 'ifacebadge', 'style': 'margin:.125em 0' }, [ - E('span', { - 'class': 'zonebadge', - 'title': zonename ? _('Part of zone %q').format(zonename) : _('No zone assigned'), - 'style': firewall.getZoneColorStyle(zonename) - }, '\u202f'), - '\u202f', network.getName(), ': ' - ]); - - if (l3dev) - span.appendChild(E('img', { - 'title': l3dev.getI18n(), - 'src': L.resource('icons/%s%s.png'.format(l3dev.getType(), l3dev.isUp() ? '' : '_disabled')) - })); - else - span.appendChild(E('em', _('(no interfaces attached)'))); - - return span; -} - -function renderNetworksTooltip(pmap) { - var res = [ null ], - zmap = {}; - - for (var i = 0; pmap && i < pmap.zones.length; i++) { - var networknames = pmap.zones[i].getNetworks(); - - for (var k = 0; k < networknames.length; k++) - zmap[networknames[k]] = pmap.zones[i].getName(); - } - - for (var i = 0; pmap && i < pmap.networks.length; i++) - res.push(E('br'), renderNetworkBadge(pmap.networks[i], zmap[pmap.networks[i].getName()])); - - if (res.length > 1) - res[0] = N_((res.length - 1) / 2, 'Part of network:', 'Part of networks:'); - else - res[0] = _('Port is not part of any network'); - - return E([], res); -} - -return baseclass.extend({ +return L.Class.extend({ title: _('Ethernet Information'), load: function() { return Promise.all([ - L.resolveDefault(callNetworkStatus(), {}), - firewall.getZones(), - network.getNetworks(), - uci.load('network') + L.resolveDefault(callLuciETHInfo(), {}) ]); }, render: function(data) { - var known_ports = [], - port_map = buildInterfaceMapping(data[1], data[2]); + var ethinfo = Array.isArray(data[0].ethinfo) ? data[0].ethinfo : []; - Object.keys(data[0]).forEach((k) => { - if (['dsa', 'ethernet'].includes(data[0][k].devtype) && data[0][k]['link-advertising'].length) - known_ports.push({ - device: k, - netdev: network.instantiateDevice(k) - }); - }); + var table = E('table', { 'class': 'table' }, [ + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th' }, _('Ethernet Name')), + E('th', { 'class': 'th' }, _('Link Status')), + E('th', { 'class': 'th' }, _('Speed')), + E('th', { 'class': 'th' }, _('Duplex')) + ]) + ]); - known_ports.sort(function(a, b) { - return L.naturalCompare(a.device, b.device); - }); + cbi_update_table(table, ethinfo.map(function(info) { + var exp1; + var exp2; - return E('div', { 'style': 'display:grid;grid-template-columns:repeat(auto-fit, minmax(100px, 1fr));margin-bottom:1em;align-items:center;justify-items:center;text-align:center' }, known_ports.map(function(port) { - var speed = port.netdev.getSpeed(), - duplex = port.netdev.getDuplex(), - pmap = port_map[port.netdev.getName()], - pzones = (pmap && pmap.zones.length) ? pmap.zones.sort(function(a, b) { return L.naturalCompare(a.getName(), b.getName()) }) : [ null ]; + if (info.status == "yes") + exp1 = _('Link Up'); + else if (info.status == "no") + exp1 = _('Link Down'); - return E('div', { 'class': 'ifacebox', 'style': 'margin:.25em;width:100px' }, [ - E('div', { 'class': 'ifacebox-head', 'style': 'font-weight:bold' }, [ port.netdev.getName() ]), - E('div', { 'class': 'ifacebox-body' }, [ - E('img', { 'src': L.resource('icons/port_%s.png').format((speed && duplex) ? 'up' : 'down') }), - E('br'), - formatSpeed(speed, duplex) - ]), - E('div', { 'class': 'ifacebox-head cbi-tooltip-container', 'style': 'display:flex' }, [ - E([], pzones.map(function(zone) { - return E('div', { - 'class': 'zonebadge', - 'style': 'cursor:help;flex:1;height:3px;' + firewall.getZoneColorStyle(zone) - }); - })), - E('span', { 'class': 'cbi-tooltip left' }, [ renderNetworksTooltip(pmap) ]) - ]), - E('div', { 'class': 'ifacebox-body' }, [ - E('div', { 'class': 'cbi-tooltip-container', 'style': 'text-align:left;font-size:80%' }, [ - '\u25b2\u202f%1024.1mB'.format(port.netdev.getTXBytes()), - E('br'), - '\u25bc\u202f%1024.1mB'.format(port.netdev.getRXBytes()), - E('span', { 'class': 'cbi-tooltip' }, formatStats(port.netdev)) - ]), - ]) - ]); + if (info.duplex == "Full") + exp2 = _('Full Duplex'); + else if (info.duplex == "Half") + exp2 = _('Half Duplex'); + else + exp2 = _('-'); + + return [ + info.name, + exp1, + info.speed, + exp2 + ]; })); + + return E([ + table + ]); } }); diff --git a/files/generic/luci-mod-status-autocore.json b/files/generic/luci-mod-status-autocore.json index bc133ab..47c4d33 100644 --- a/files/generic/luci-mod-status-autocore.json +++ b/files/generic/luci-mod-status-autocore.json @@ -3,8 +3,7 @@ "description": "Grant access to autocore", "read": { "ubus": { - "luci": [ "getCPUInfo", "getTempInfo", "getCPUBench", "getCPUUsage" ], - "network.device": [ "status" ] + "luci": [ "getCPUInfo", "getETHInfo", "getTempInfo", "getCPUBench", "getCPUUsage" ] } } }