ethernet information support both DSA and GSW (#344)

This commit is contained in:
wsk170 2024-11-21 12:52:21 +08:00 committed by GitHub
parent 0e2fe86ae5
commit b5d6e1fe4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,7 +1,6 @@
'use strict'; 'use strict';
'require baseclass'; 'require baseclass';
'require rpc'; 'require rpc';
'require uci';
'require network'; 'require network';
var callSwconfigFeatures = rpc.declare({ var callSwconfigFeatures = rpc.declare({
@ -30,45 +29,60 @@ var callLuciNetworkDevices = rpc.declare({
expect: { '': {} } expect: { '': {} }
}); });
var isDSA = false;
const ethStyle = {
box: 'max-width: 100px;',
head: `
border-radius: 7px 7px 0 0;
text-align: center;
font-weight: bold;`,
body: `
border: 1px solid lightgrey;
border-radius: 0 0 7px 7px;
display: flex; flex-direction: column;
align-items: center; justify-content: center;`,
icon: 'margin: 5px; width: 40px;',
speed: 'font-size: 0.8rem; font-weight: bold;',
traffic: `
border-top: 1px solid lightgrey;
font-size: 0.8rem;`
};
function formatSpeed(speed) { function formatSpeed(speed) {
if (!speed) return '-'; if (speed <= 0) return '-';
return speed < 1000 ? `${speed} M` : `${speed / 1000} GbE`; const speedInt = parseInt(speed);
if (isNaN(speedInt)) return '-';
return speedInt < 1000 ? `${speedInt} M` : `${speedInt / 1000} GbE`;
} }
function getPortColor(link, duplex) { function getPortColor(carrier, duplex) {
if (!link) return 'background-color: whitesmoke;'; if (!carrier) return 'background-color: whitesmoke;';
const color = duplex == 'full' || duplex ? 'greenyellow' : 'darkorange'; if (duplex === 'full' || duplex === true)
return 'background-color: ' + color; return 'background-color: greenyellow;';
return 'background-color: darkorange';
} }
function getPortIcon(link) { function getPortIcon(carrier) {
return L.resource(`icons/port_${link ? 'up' : 'down'}.png`); return L.resource(`icons/port_${carrier ? 'up' : 'down'}.png`);
} }
return L.Class.extend({ return baseclass.extend({
title: _('Ethernet Information'), title: _('Ethernet Information'),
load: function () { load: function () {
return network.getSwitchTopologies().then(function (topologies) { return network.getSwitchTopologies().then(function (topologies) {
let tasks = []; if (Object.keys(topologies).length === 0) {
isDSA = true;
for (let switchName in topologies) { return Promise.all([
tasks.push( L.resolveDefault(callLuciBoardJSON(), {}),
callSwconfigFeatures(switchName).then( L.resolveDefault(callLuciNetworkDevices(), {})
L.bind(function (features) { ]);
this.features = features;
}, topologies[switchName])
)
);
tasks.push(
callSwconfigPortState(switchName).then(
L.bind(function (ports) {
this.portstate = ports;
}, topologies[switchName])
)
);
} }
callSwconfigPortState('switch0').then((ports) => {
topologies.switch0.portstate = ports;
});
return Promise.all([ return Promise.all([
topologies, topologies,
L.resolveDefault(callLuciBoardJSON(), {}), L.resolveDefault(callLuciBoardJSON(), {}),
@ -77,38 +91,23 @@ return L.Class.extend({
}); });
}, },
render: function (data) { render_gsw: function (data) {
const topologies = data[0]; const topologies = data[0];
const board = data[1]; const board = data[1];
const netdevs = data[2]; const netdevs = data[2];
const boxStyle = 'max-width: 100px;';
const boxHeadStyle =
'border-radius: 7px 7px 0 0;' +
'text-align: center;' +
'font-weight:bold;';
const boxbodyStyle =
'border: 1px solid lightgrey;' +
'border-radius: 0 0 7px 7px;' +
'display:flex; flex-direction: column;' +
'align-items: center; justify-content:center;';
const iconStyle = 'margin: 5px; width: 40px;';
const speedStyle = 'font-size:0.8rem; font-weight:bold;';
const trafficStyle =
'border-top: 1px solid lightgrey;' + 'font-size:0.8rem;';
const ethPorts = []; const ethPorts = [];
const wan = netdevs[board.network.wan.device]; const wan = netdevs[board.network.wan.device];
const { speed, duplex, carrier } = wan.link; const { speed, duplex, carrier } = wan.link;
let portIcon = getPortIcon(carrier); let portIcon = getPortIcon(carrier);
let portColor = getPortColor(carrier, duplex); let portColor = getPortColor(carrier, duplex);
ethPorts.push( ethPorts.push(
E('div', { style: boxStyle }, [ E('div', { style: ethStyle.box }, [
E('div', { style: boxHeadStyle + portColor }, 'WAN'), E('div', { style: ethStyle.head + portColor }, 'WAN'),
E('div', { style: boxbodyStyle }, [ E('div', { style: ethStyle.body }, [
E('img', { style: iconStyle, src: portIcon }), E('img', { style: ethStyle.icon, src: portIcon }),
E('div', { style: speedStyle }, formatSpeed(speed)), E('div', { style: ethStyle.speed }, formatSpeed(speed)),
E('div', { style: trafficStyle }, [ E('div', { style: ethStyle.traffic }, [
'\u25b2\u202f%1024.1mB'.format(wan.stats.tx_bytes), '\u25b2\u202f%1024.1mB'.format(wan.stats.tx_bytes),
E('br'), E('br'),
'\u25bc\u202f%1024.1mB'.format(wan.stats.rx_bytes) '\u25bc\u202f%1024.1mB'.format(wan.stats.rx_bytes)
@ -119,20 +118,22 @@ return L.Class.extend({
const switch0 = topologies.switch0; const switch0 = topologies.switch0;
for (const port of switch0.ports) { for (const port of switch0.ports) {
if (!port.label.startsWith('LAN')) continue; const label = port.label.toUpperCase();
if (!label.startsWith('LAN')) continue;
const { link, duplex, speed } = switch0.portstate[port.num]; const { link, duplex, speed } = switch0.portstate[port.num];
portIcon = getPortIcon(link); portIcon = getPortIcon(link);
portColor = getPortColor(link, duplex); portColor = getPortColor(link, duplex);
const txrx = { tx_bytes: 0, rx_bytes: 0 }; const txrx = { tx_bytes: 0, rx_bytes: 0 };
const lanStats = netdevs['br-lan'].stats; const stats = netdevs['br-lan'].stats;
const { tx_bytes, rx_bytes } = link ? lanStats : txrx; const { tx_bytes, rx_bytes } = link ? stats : txrx;
ethPorts.push( ethPorts.push(
E('div', { style: boxStyle }, [ E('div', { style: ethStyle.box }, [
E('div', { style: boxHeadStyle + portColor }, port.label), E('div', { style: ethStyle.head + portColor }, port.label),
E('div', { style: boxbodyStyle }, [ E('div', { style: ethStyle.body }, [
E('img', { style: iconStyle, src: portIcon }), E('img', { style: ethStyle.icon, src: portIcon }),
E('div', { style: speedStyle }, formatSpeed(speed)), E('div', { style: ethStyle.speed }, formatSpeed(speed)),
E('div', { style: trafficStyle }, [ E('div', { style: ethStyle.traffic }, [
'\u25b2\u202f%1024.1mB'.format(tx_bytes), '\u25b2\u202f%1024.1mB'.format(tx_bytes),
E('br'), E('br'),
'\u25bc\u202f%1024.1mB'.format(rx_bytes) '\u25bc\u202f%1024.1mB'.format(rx_bytes)
@ -142,10 +143,48 @@ return L.Class.extend({
); );
} }
const gridStyle = return ethPorts;
'display:grid; grid-gap: 5px 5px;' + },
'grid-template-columns:repeat(auto-fit, minmax(70px, 1fr));' +
'margin-bottom:1em'; render_dsa: function (data) {
const board = data[0];
const netdevs = data[1];
const ethPorts = [];
const wan = board.network.wan.device;
let devices = `${wan},lan0,lan1,lan2,lan3,lan4,lan5,lan6`;
devices = devices.split(',');
for (const device of devices) {
if (device in netdevs === false) continue;
const dev = netdevs[device];
const { speed, duplex, carrier } = dev.link;
let portIcon = getPortIcon(carrier);
let portColor = getPortColor(carrier, duplex);
ethPorts.push(
E('div', { style: ethStyle.box }, [
E('div', { style: ethStyle.head + portColor }, dev.name),
E('div', { style: ethStyle.body }, [
E('img', { style: ethStyle.icon, src: portIcon }),
E('div', { style: ethStyle.speed }, formatSpeed(speed)),
E('div', { style: ethStyle.traffic }, [
'\u25b2\u202f%1024.1mB'.format(dev.stats.tx_bytes),
E('br'),
'\u25bc\u202f%1024.1mB'.format(dev.stats.rx_bytes)
])
])
])
);
}
return ethPorts;
},
render: function (data) {
const ethPorts = isDSA ? this.render_dsa(data) : this.render_gsw(data);
const gridStyle = `
display: grid; grid-gap: 5px 5px;
grid-template-columns: repeat(auto-fit, minmax(70px, 1fr));
margin-bottom: 1em`;
return E('div', { style: gridStyle }, ethPorts); return E('div', { style: gridStyle }, ethPorts);
} }
}); });