diff --git a/internal/birdfmt/protocol_summary.go b/internal/birdfmt/protocol_summary.go index 931136e..43dd7c2 100644 --- a/internal/birdfmt/protocol_summary.go +++ b/internal/birdfmt/protocol_summary.go @@ -11,6 +11,24 @@ type ProtocolsSummary struct { RawLineCount int } +// isBGPProtocolSummaryRow is true for BIRD "show protocols" summary rows where the +// second column (Proto) is BGP. Substring checks are unsafe: names like evobgp_* contain "bgp". +func isBGPProtocolSummaryRow(line string) bool { + line = strings.TrimSpace(line) + if line == "" { + return false + } + low := strings.ToLower(line) + if strings.HasPrefix(low, "name") || strings.HasPrefix(low, "table") { + return false + } + fields := strings.Fields(line) + if len(fields) < 2 { + return false + } + return strings.EqualFold(fields[1], "BGP") +} + // SummarizeProtocolsOutput extracts BGP session heuristics from birdc output. func SummarizeProtocolsOutput(output string) ProtocolsSummary { var s ProtocolsSummary @@ -22,14 +40,12 @@ func SummarizeProtocolsOutput(output string) ProtocolsSummary { continue } low := strings.ToLower(line) - if strings.HasPrefix(low, "name") || strings.HasPrefix(low, "table") { + if !isBGPProtocolSummaryRow(line) { continue } - if strings.Contains(low, "bgp") { - s.BGPSessionsTotal++ - if strings.Contains(low, "established") { - s.BGPEstablished++ - } + s.BGPSessionsTotal++ + if strings.Contains(low, "established") { + s.BGPEstablished++ } } return s diff --git a/internal/birdfmt/protocol_summary_test.go b/internal/birdfmt/protocol_summary_test.go index d7c512d..c416597 100644 --- a/internal/birdfmt/protocol_summary_test.go +++ b/internal/birdfmt/protocol_summary_test.go @@ -12,3 +12,14 @@ uplink BGP --- start 10:00:01 Established t.Fatalf("got %+v", s) } } + +func TestSummarizeProtocolsOutput_evoBGPNameNotCountedAsBGP(t *testing.T) { + sample := `Name Proto Table State Since Info +evobgp_prefixes_v4 Static master4 up 17:32:14.631 +evobgp_prefixes_v6 Static master6 up 17:32:14.631 +` + s := SummarizeProtocolsOutput(sample) + if s.BGPSessionsTotal != 0 || s.BGPEstablished != 0 { + t.Fatalf("evobgp_* static names must not match substring bgp: got %+v", s) + } +} diff --git a/internal/birdfmt/protocols.go b/internal/birdfmt/protocols.go index 5c57a87..bfa91e7 100644 --- a/internal/birdfmt/protocols.go +++ b/internal/birdfmt/protocols.go @@ -41,7 +41,7 @@ func CountEstablishedBGPSessions(showProtocolsOutput string) int { if line == "" || strings.HasPrefix(line, "name") || strings.HasPrefix(strings.ToLower(line), "table") { continue } - if !strings.Contains(strings.ToLower(line), "bgp") { + if !isBGPProtocolSummaryRow(line) { continue } if strings.Contains(strings.ToLower(line), "established") { diff --git a/web/src/lib/components/app/scroll-pre-block.svelte b/web/src/lib/components/app/scroll-pre-block.svelte new file mode 100644 index 0000000..8df9161 --- /dev/null +++ b/web/src/lib/components/app/scroll-pre-block.svelte @@ -0,0 +1,29 @@ + + +
{text}
+