diff --git a/html/main.js b/html/main.js index c3fec057..27f78aef 100644 --- a/html/main.js +++ b/html/main.js @@ -1020,6 +1020,13 @@ const conf_cmds = [ /^stp\s+port\s+\d{1,2}\s+guard\s+(none|bpdu|root)$/, /^stp\s+port\s+\d{1,2}\s+filter\s+(on|off)$/, /^stp\s+port\s+\d{1,2}\s+p2p\s+(auto|on|off)$/, + /^stp\s+lag\s+[1-4]\s+(on|off)$/, + /^stp\s+lag\s+[1-4]\s+edge\s+(on|off|auto)$/, + /^stp\s+lag\s+[1-4]\s+cost\s+\d{1,9}$/, + /^stp\s+lag\s+[1-4]\s+prio\s+\d{1,3}$/, + /^stp\s+lag\s+[1-4]\s+guard\s+(none|bpdu|root)$/, + /^stp\s+lag\s+[1-4]\s+filter\s+(on|off)$/, + /^stp\s+lag\s+[1-4]\s+p2p\s+(auto|on|off)$/, /^igmp\s+(on|off)$/, /^mtu\s+\d{1,2}\s+\d+$/, /^bw\s+(in|out)\s+\d{1,2}\s+\S+$/, @@ -1055,6 +1062,7 @@ const conf_overwrite = [ /^isolate\s+\d{1,2}\b/, /^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/, /^stp\s+port\s+\d{1,2}\s+(edge|cost|prio|guard|filter|p2p)\b/, + /^stp\s+lag\s+[1-4]\s+(edge|cost|prio|guard|filter|p2p)\b/, /^igmp\b/, /^mtu\s+\d{1,2}\b/, /^bw\s+(in|out)\s+\d{1,2}\b/, @@ -2601,45 +2609,58 @@ function num(id, min, max, onch) { return n; } +function members(mask) { + const a = []; + for (let i = 0; i < numPorts; i++) + if (mask & (1 << i)) a.push(logToPhysPort[i]); + return a.join(","); +} + function buildPortsTable(ports) { const tbl = document.getElementById("stpPortsTbl"); const stat = document.getElementById("stpStatTbl"); for (const p of [...ports].sort((a, b) => a.p - b.p)) { + p.n = p.lag ? "lag " + p.lag : "port " + p.p; + p.k = p.lag ? "L" + p.lag : p.p; const tr = tbl.insertRow(); - tr.insertCell().textContent = p.p; - tr.insertCell().appendChild(sel("en_" + p.p, + tr.insertCell().textContent = p.lag + ? "LAG" + p.lag + " (" + members(p.mbr) + ")" + : p.p; + tr.insertCell().appendChild(sel("en_" + p.k, [["on","Enable"],["off","Disable"]], - e => stpCmd("stp port " + p.p + " " + e.target.value))); - const pc = num("cost_" + p.p, 0, 200000000, - e => stpCmd("stp port " + p.p + " cost " + e.target.value)); + e => stpCmd("stp " + p.n + " " + e.target.value))); + const pc = num("cost_" + p.k, 0, 200000000, + e => stpCmd("stp " + p.n + " cost " + e.target.value)); pc.style.width = "7em"; pc.title = "0 - 200000000 (0 = Auto)"; tr.insertCell().appendChild(pc); - const pr = sel("prio_" + p.p, [], - e => stpCmd("stp port " + p.p + " prio " + e.target.value)); + const pr = sel("prio_" + p.k, [], + e => stpCmd("stp " + p.n + " prio " + e.target.value)); for (let v = 0; v <= 240; v += 16) { const o = document.createElement("option"); o.value = v; o.textContent = v + (v === 128 ? " (default)" : ""); pr.appendChild(o); } tr.insertCell().appendChild(pr); - tr.insertCell().appendChild(sel("edge_" + p.p, + tr.insertCell().appendChild(sel("edge_" + p.k, [["auto","Auto"],["on","Enable"],["off","Disable"]], - e => stpCmd("stp port " + p.p + " edge " + e.target.value))); - tr.insertCell().appendChild(sel("filt_" + p.p, + e => stpCmd("stp " + p.n + " edge " + e.target.value))); + tr.insertCell().appendChild(sel("filt_" + p.k, [["off","Disable"],["on","Enable"]], - e => stpCmd("stp port " + p.p + " filter " + e.target.value))); - tr.insertCell().appendChild(sel("guard_" + p.p, + e => stpCmd("stp " + p.n + " filter " + e.target.value))); + tr.insertCell().appendChild(sel("guard_" + p.k, [["none","None"],["bpdu","BPDU"],["root","Root"]], - e => stpCmd("stp port " + p.p + " guard " + e.target.value))); - tr.insertCell().appendChild(sel("p2p_" + p.p, + e => stpCmd("stp " + p.n + " guard " + e.target.value))); + tr.insertCell().appendChild(sel("p2p_" + p.k, [["auto","Auto"],["on","Enable"],["off","Disable"]], - e => stpCmd("stp port " + p.p + " p2p " + e.target.value))); + e => stpCmd("stp " + p.n + " p2p " + e.target.value))); const sr = stat.insertRow(); - sr.insertCell().textContent = p.p; + sr.insertCell().textContent = p.lag + ? "LAG" + p.lag + " (" + members(p.mbr) + ")" + : p.p; for (const id of ["st","role","db","dp","dc","oe","op"]) - sr.insertCell().id = id + "_" + p.p; + sr.insertCell().id = id + "_" + p.k; } stpRows = ports.length; } @@ -2672,18 +2693,19 @@ function fetchStp() { + " \u2014 topology changes: " + parseInt(s.tc, 16)) : ""; for (const p of s.ports) { + const k = p.lag ? "L" + p.lag : p.p; const trip = (p.f & PF_TRIPPED) ? " (guard!)" : ""; - document.getElementById("st_" + p.p).textContent = + document.getElementById("st_" + k).textContent = s.on ? STP_STATES[p.st] + trip : "-"; - document.getElementById("role_" + p.p).textContent = + document.getElementById("role_" + k).textContent = s.on ? STP_ROLES[p.role] : "-"; - document.getElementById("db_" + p.p).textContent = s.on ? fmtBridgeId(p.db) : "-"; - document.getElementById("dp_" + p.p).textContent = + document.getElementById("db_" + k).textContent = s.on ? fmtBridgeId(p.db) : "-"; + document.getElementById("dp_" + k).textContent = s.on ? (parseInt(p.dp.slice(0, 2), 16) + "-" + parseInt(p.dp.slice(2), 16)) : "-"; - document.getElementById("dc_" + p.p).textContent = s.on ? parseInt(p.dc, 16) : "-"; - document.getElementById("oe_" + p.p).textContent = + document.getElementById("dc_" + k).textContent = s.on ? parseInt(p.dc, 16) : "-"; + document.getElementById("oe_" + k).textContent = s.on ? ((p.f & PF_OPEREDGE) ? "True" : "False") : "-"; - document.getElementById("op_" + p.p).textContent = s.on ? (p.p2 == 2 ? "False" : "True") : "-"; + document.getElementById("op_" + k).textContent = s.on ? (p.p2 == 2 ? "False" : "True") : "-"; } if (stpDirty) return; @@ -2695,15 +2717,16 @@ function fetchStp() { document.getElementById("bFwd").value = s.fwd; document.getElementById("bTxhold").value = s.txhold; for (const p of s.ports) { - document.getElementById("en_" + p.p).value = (p.f & PF_ENABLED) ? "on" : "off"; - document.getElementById("edge_" + p.p).value = + const k = p.lag ? "L" + p.lag : p.p; + document.getElementById("en_" + k).value = (p.f & PF_ENABLED) ? "on" : "off"; + document.getElementById("edge_" + k).value = (p.f & PF_ADMEDGE) ? "on" : ((p.f & PF_AUTOEDGE) ? "auto" : "off"); - document.getElementById("cost_" + p.p).value = parseInt(p.pc, 16); - document.getElementById("prio_" + p.p).value = p.prio; - document.getElementById("p2p_" + p.p).value = ["auto","on","off"][p.p2]; - document.getElementById("guard_" + p.p).value = + document.getElementById("cost_" + k).value = parseInt(p.pc, 16); + document.getElementById("prio_" + k).value = p.prio; + document.getElementById("p2p_" + k).value = ["auto","on","off"][p.p2]; + document.getElementById("guard_" + k).value = (p.f & PF_BPDUGUARD) ? "bpdu" : ((p.f & PF_ROOTGUARD) ? "root" : "none"); - document.getElementById("filt_" + p.p).value = (p.f & PF_FILTER) ? "on" : "off"; + document.getElementById("filt_" + k).value = (p.f & PF_FILTER) ? "on" : "off"; } } };