diff --git a/pkg/telemetry/prometheus/node_linux.go b/pkg/telemetry/prometheus/node_linux.go index e88dedbe2..002f3967c 100644 --- a/pkg/telemetry/prometheus/node_linux.go +++ b/pkg/telemetry/prometheus/node_linux.go @@ -41,13 +41,14 @@ func getTCStats() (packets, drops uint32, err error) { // Newer kernels report stats via TCA_STATS2 (Stats2), while older kernels // only populate the legacy TCA_STATS attribute (Stats). Prefer Stats2 and // fall back to Stats so counters are collected on both. - switch { - case qdisc.Stats2 != nil: - packets = packets + qdisc.Stats2.Packets - drops = drops + qdisc.Stats2.Drops - case qdisc.Stats != nil: - packets = packets + qdisc.Stats.Packets - drops = drops + qdisc.Stats.Drops + // + // However, go-tc (through v0.4.8 and current main) mis-parses the nested TCA_STATS2 + // as a flat struct, so Stats2.Packets/.Drops are garbage. The legacy + // TCA_STATS blob is a real flat struct and is parsed correctly, and modern + // kernels populate BOTH — so prefer Stats. + if qdisc.Stats != nil { + packets += qdisc.Stats.Packets + drops += qdisc.Stats.Drops } }