Merge pull request #344 from DrDoof/feat/walk-l2

html: move the L2 table walk into a shared walkL2() helper
This commit is contained in:
René van Dorst
2026-08-15 21:38:43 +00:00
committed by GitHub
3 changed files with 97 additions and 65 deletions
+7 -40
View File
@@ -1,7 +1,3 @@
var l2GetInterval;
var l2Entries = [];
var l2CurrentEntry = 0;
function fillStats() { function fillStats() {
var tbl = document.getElementById('statstable'); var tbl = document.getElementById('statstable');
if (!numPorts) if (!numPorts)
@@ -118,7 +114,6 @@ function fillL2(s)
s = uniq(s); s = uniq(s);
l2All = s; l2All = s;
renderL2(); renderL2();
l2Entries = [];
} }
function paintL2(tbl, s) function paintL2(tbl, s)
@@ -147,48 +142,20 @@ function paintL2(tbl, s)
} }
function getL2() { function getL2() {
var xhttp = new XMLHttpRequest(); walkL2(function(entries, ok) {
xhttp.onreadystatechange = function() { if (ok) {
if (this.readyState == 4 && this.status == 200) { for (var i = 0; i < entries.length; i++)
var s = JSON.parse(xhttp.responseText); entries[i].type = entries[i].type == "s" ? t('l2_static') : t('l2_learned');
var s = s.map(function(e) { fillL2(entries);
e.vlan = parseInt(e.vlan, 16);
e.idx = parseInt(e.idx, 16);
e.type = e.type == "s" ? t('l2_static') : t('l2_learned');
e.port = e.port == 9 ? 'CPU' : logToPhysPort[e.port];
return e;
});
l2Entries.push(...s);
if (l2Entries >= 4096) {
l2Entries = [];
l2CurrentEntry = 0;
clearInterval(l2GetInterval);
return;
}
var w = 0;
for (var i = l2Entries.length-1; i > 0; i--) {
if (l2Entries[0].idx == l2Entries[i].idx) {
w = 1;
break;
}
}
if (w) {
l2CurrentEntry = 0;
fillL2(l2Entries);
} else {
l2CurrentEntry = s[s.length-1].idx + 1;
}
} }
}; setTimeout(getL2, 1000);
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true); });
xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
window.addEventListener("load", function() { window.addEventListener("load", function() {
update( () => { update( () => {
getL2(); getL2();
const interval = setInterval(update, 2000); const interval = setInterval(update, 2000);
l2GetInterval = setInterval(getL2, 1000);
});; });;
}); });
+63
View File
@@ -285,3 +285,66 @@ function sendXHTTP(x)
currentRequests.push(x); currentRequests.push(x);
} }
function walkL2(onDone)
{
var entries = [];
var idx = 0;
var tries = 0;
function retry() {
if (++tries < 3) {
setTimeout(page, 1000);
return;
}
onDone(entries, false);
}
function page() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState != 4)
return;
if (this.status != 200) {
retry();
return;
}
var s;
try {
s = JSON.parse(xhttp.responseText);
} catch (err) {
retry();
return;
}
tries = 0;
s = s.map(function(e) {
e.vlan = parseInt(e.vlan, 16);
e.idx = parseInt(e.idx, 16);
e.port = e.port == 9 ? 'CPU' : logToPhysPort[e.port];
return e;
});
if (!s.length) {
onDone(entries, true);
return;
}
entries.push(...s);
for (var i = entries.length - 1; i > 0; i--) {
if (entries[0].idx == entries[i].idx) {
onDone(entries, true);
return;
}
}
if (entries.length >= 4096) {
onDone(entries, true);
return;
}
idx = s[s.length - 1].idx + 1;
setTimeout(page, 1000);
};
xhttp.open("GET", "/l2.json?idx=" + idx, true);
xhttp.timeout = 1500;
sendXHTTP(xhttp);
}
page();
}
+27 -25
View File
@@ -356,6 +356,7 @@ void send_l2(uint16_t idx)
*/ */
__xdata uint16_t entry = idx & 0xfff; __xdata uint16_t entry = idx & 0xfff;
__xdata uint16_t first_entry = 0xffff; // An illegal entry index __xdata uint16_t first_entry = 0xffff; // An illegal entry index
bool first = true;
char_to_html('['); char_to_html('[');
while (1) { while (1) {
entries_left--; entries_left--;
@@ -369,9 +370,22 @@ void send_l2(uint16_t idx)
} while (sfr_data[3] & TBL_EXECUTE); } while (sfr_data[3] & TBL_EXECUTE);
reg_read_m(RTL837x_L2_DATA_OUT_B); reg_read_m(RTL837x_L2_DATA_OUT_B);
if ((sfr_data[0] & 0x20)) { // Check entry is valid bool valid = (sfr_data[0] & 0x20) != 0;
if (valid) {
/* separator + 74-byte worst-case entry + closing "]" */
if (slen + 76 > TCP_OUTBUF_SIZE)
break;
if (!first)
char_to_html(',');
first = false;
// VLAN, taken from the read above instead of reading the register twice
slen += strtox(outbuf + slen, "{\"vlan\":\"");
charhex_to_html(sfr_data[0] & 0x0f);
byte_to_html(sfr_data[1]);
// MAC // MAC
slen += strtox(outbuf + slen, "{\"mac\":\""); slen += strtox(outbuf + slen, "\",\"mac\":\"");
byte_to_html(sfr_data[2]); char_to_html(':'); byte_to_html(sfr_data[2]); char_to_html(':');
byte_to_html(sfr_data[3]); char_to_html(':'); byte_to_html(sfr_data[3]); char_to_html(':');
port = (sfr_data[0] >> 6) & 0x3; port = (sfr_data[0] >> 6) & 0x3;
@@ -381,12 +395,6 @@ void send_l2(uint16_t idx)
byte_to_html(sfr_data[2]); char_to_html(':'); byte_to_html(sfr_data[2]); char_to_html(':');
byte_to_html(sfr_data[3]); byte_to_html(sfr_data[3]);
// VLAN
slen += strtox(outbuf + slen, "\",\"vlan\":\"");
reg_read_m(RTL837x_L2_DATA_OUT_B);
charhex_to_html(sfr_data[0] & 0x0f);
byte_to_html(sfr_data[1]);
// type // type
reg_read_m(RTL837x_L2_DATA_OUT_C); reg_read_m(RTL837x_L2_DATA_OUT_C);
if (sfr_data[2] & 0x1) if (sfr_data[2] & 0x1)
@@ -396,32 +404,26 @@ void send_l2(uint16_t idx)
port |= (sfr_data[3] & 0x3) << 2; port |= (sfr_data[3] & 0x3) << 2;
itoa_html(port); itoa_html(port);
}
// Index // Index
reg_read_m(RTL837x_TBL_DATA_0); reg_read_m(RTL837x_TBL_DATA_0);
entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3]; entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3];
if (valid) {
slen += strtox(outbuf + slen, ",\"idx\":\""); slen += strtox(outbuf + slen, ",\"idx\":\"");
byte_to_html(entry >> 8); byte_to_html(entry >> 8);
byte_to_html(entry); byte_to_html(entry);
char_to_html('"'); char_to_html('"');
char_to_html('}'); char_to_html('}');
entry += 1; // We want the next entry following after the current entry
} else {
reg_read_m(RTL837x_TBL_DATA_0);
entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3] + 1;
} }
if (first_entry == 0xffff) { entry += 1; // We want the next entry following after the current entry
char_to_html(',');
if (first_entry == 0xffff)
first_entry = entry; first_entry = entry;
} else { else if (first_entry == entry || !entries_left)
if (first_entry == entry || !entries_left) { break;
char_to_html(']');
break;
} else {
char_to_html(',');
}
}
} }
char_to_html(']');
} }