From 38b19820e464f4555566401afa2df50b7cf83817 Mon Sep 17 00:00:00 2001 From: d00f Date: Fri, 14 Aug 2026 15:32:01 +0200 Subject: [PATCH] stp: show how long ago each port last heard a BPDU The status output named state, role and edge, none of which separates a port nobody is speaking (R)STP to from a port whose BPDUs we are dropping. Both look the same: forwarding, designated, edge, and the tree rooted at ourselves. stp_in() leaves on eight different conditions, from a short frame through an unexpected LLC header to a disabled port, and none of them says anything. stp_bpdu_age was already maintained for the ageing rules, so this only prints it, in seconds and capped at 255. A column that counts up means nothing is arriving; a column that stays near zero means frames are arriving and any disagreement about the tree is ours. Eighty two bytes of BANK2 and two of xdata, most of it the sixteen bit divide by the tick rate. It comes out of a branch that gives back three hundred and twenty eight, so it is affordable, and printing raw ticks to save it would put the reader back to converting in their head. --- rtl837x_stp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rtl837x_stp.c b/rtl837x_stp.c index f8ee6b9..ca56f8d 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -61,6 +61,7 @@ __xdata struct bridge root_bridge; __xdata uint32_t root_bridge_cost; /* our cost to the root (rx cost + root port cost) */ __xdata uint8_t stp_root_port; /* 0xff = we are the root */ __xdata uint16_t stp_tc_count; +__xdata uint16_t stp_scratch16; /* scratch for status printing only */ __xdata uint16_t port_timers[10]; /* listen-period countdown (0 = not listening) */ __xdata uint16_t port_hello[10]; /* hello TX countdown */ @@ -176,7 +177,7 @@ static void stp_status(void) print_string("changes "); print_short(stp_tc_count); write_char('\n'); - print_string("port state role edge\n"); + print_string("port state role edge bpdu\n"); reg_read_m(RTL837X_MSTP_STATES); for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) { write_char(' '); @@ -187,6 +188,13 @@ static void stp_status(void) print_byte(stp_i == stp_root_port ? 1 : 2); print_string(" "); print_byte(stp_pflags[stp_i] & STP_PF_OPEREDGE ? 1 : 0); + /* Seconds since the last BPDU on this port, capped at 255. Without + * it nothing in the output separates "nobody is speaking (R)STP + * out there" from "we are dropping what arrives", and stp_in() + * leaves on eight different conditions without saying so. */ + print_string(" "); + stp_scratch16 = stp_bpdu_age[stp_i] / STP_HZ; + itoa(stp_scratch16 > 255 ? 255 : (uint8_t)stp_scratch16); write_char('\n'); } }