Status page: IPv6 first in a neighbour's pair of sessions

Of <stem>-v6 and <stem>-v4, the IPv6 session is listed first and carries
the name in full; IPv4 is under it. The same order in the lookup's list of
peers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Rayhaan JaufeerallyandClaude Fable 5.1 committed 2026-10-07 23:19:56 +02:00
1 parent 277b973f1a
commit 430addcf20
2 files changed
+16 -7

No files matched your search

+14 -5
View File
@@ -412,6 +412,17 @@ from <select id="lookup-peer"><option value="">any peer</option></select>
return p.state === 'Established' && p.expected_routes > 0 && p.routes != null return p.state === 'Established' && p.expected_routes > 0 && p.routes != null
&& p.routes < p.expected_routes / 2 && now() - p.established_at_unix > SETTLING_SECS; && p.routes < p.expected_routes / 2 && now() - p.established_at_unix > SETTLING_SECS;
} }
// Peers in name order, except that the IPv6 session of a neighbour
// (<stem>-v6) comes before its IPv4 one: IPv6 is the network's present,
// IPv4 what is still carried along.
const FAMILY_SUFFIX = /^(.*)-v([46])$/;
function nameOrder(a, c) {
const [sa, fa] = FAMILY_SUFFIX.exec(a)?.slice(1) || [a, ''];
const [sc, fc] = FAMILY_SUFFIX.exec(c)?.slice(1) || [c, ''];
return sa.localeCompare(sc) || fc.localeCompare(fa);
}
const byName = (a, c) => nameOrder(a.name || a.peer_addr, c.name || c.peer_addr);
// Where a peer stands, for the strip and for sorting: 0 failed, 1 // Where a peer stands, for the strip and for sorting: 0 failed, 1
// degraded, 2 normal, 3 inactive and expected. // degraded, 2 normal, 3 inactive and expected.
function peerRank(p) { function peerRank(p) {
@@ -524,9 +535,8 @@ from <select id="lookup-peer"><option value="">any peer</option></select>
if (!peers.length) { setHTML(b, '<tr><td colspan="9" class="dim">No peers configured and none connected.</td></tr>'); return; } if (!peers.length) { setHTML(b, '<tr><td colspan="9" class="dim">No peers configured and none connected.</td></tr>'); return; }
const problemsOnly = $('peers-problems').checked; const problemsOnly = $('peers-problems').checked;
// The IPv4 and IPv6 sessions of one neighbour, named <stem>-v4 and // The IPv4 and IPv6 sessions of one neighbour, named <stem>-v4 and
// <stem>-v6, are one neighbour to the reader: listed together, the // <stem>-v6, are one neighbour to the reader: listed together, IPv6
// name once in full and once quietly, joined down the side. // first, the name once in full and once quietly, joined down the side.
const FAMILY_SUFFIX = /^(.*)-v([46])$/;
const row = (p, pair) => { const row = (p, pair) => {
const up = p.state === 'Established'; const up = p.state === 'Established';
const family = p.name && FAMILY_SUFFIX.exec(p.name); const family = p.name && FAMILY_SUFFIX.exec(p.name);
@@ -559,7 +569,6 @@ from <select id="lookup-peer"><option value="">any peer</option></select>
if (sameStem(list[i - 1])) return row(p, 'pair-b'); if (sameStem(list[i - 1])) return row(p, 'pair-b');
return row(p); return row(p);
}).join(''); }).join('');
const byName = (a, c) => (a.name || a.peer_addr).localeCompare(c.name || c.peer_addr);
let html = ''; let html = '';
// What needs attention first, whoever it is; then everyone by what // What needs attention first, whoever it is; then everyone by what
// they are to us. // they are to us.
@@ -661,7 +670,7 @@ from <select id="lookup-peer"><option value="">any peer</option></select>
function renderPeerChoices() { function renderPeerChoices() {
const chosen = lookup().peer; const chosen = lookup().peer;
const names = [...new Set(state.peers.filter(p => p.state === 'Established') const names = [...new Set(state.peers.filter(p => p.state === 'Established')
.map(p => p.name || p.peer_addr.replace(/:\d+$/, '').replace(/^\[|\]$/g, '')))].sort(); .map(p => p.name || p.peer_addr.replace(/:\d+$/, '').replace(/^\[|\]$/g, '')))].sort(nameOrder);
if (chosen && !names.includes(chosen)) names.push(chosen); if (chosen && !names.includes(chosen)) names.push(chosen);
setHTML($('lookup-peer'), '<option value="">any peer</option>' + setHTML($('lookup-peer'), '<option value="">any peer</option>' +
names.map(n => `<option value="${esc(n)}"${n === chosen ? ' selected' : ''}>${esc(n)}</option>`).join('')); names.map(n => `<option value="${esc(n)}"${n === chosen ? ' selected' : ''}>${esc(n)}</option>`).join(''));
+2 -2
View File
@@ -40,8 +40,8 @@ Below the status line, the page displays the following information:
session properties, number of accepted routes, rejected announcements, session properties, number of accepted routes, rejected announcements,
and held routes, and its last error. Neighbors that need attention are and held routes, and its last error. Neighbors that need attention are
listed first; the others are grouped by role. The IPv4 and IPv6 sessions listed first; the others are grouped by role. The IPv4 and IPv6 sessions
of one neighbor, named `NAME-v4` and `NAME-v6`, are listed together and of one neighbor, named `NAME-v4` and `NAME-v6`, are listed together,
joined by a bar. The **problems only** option hides the neighbors that IPv6 first, and joined by a bar. The **problems only** option hides the neighbors that
need no attention; the **compact** option removes the next hop and need no attention; the **compact** option removes the next hop and
session columns, for a small or distant screen, and is remembered by the session columns, for a small or distant screen, and is remembered by the
browser. browser.