struct stp_timer forward_delay_timer; /* 8.5.6.2: State change timer. */
struct stp_timer hold_timer; /* 8.5.6.3: BPDU rate limit timer. */
+ int tx_count; /* Number of BPDUs transmitted. */
+ int rx_count; /* Number of valid BPDUs received. */
+ int error_count; /* Number of bad BPDUs received. */
+
bool state_changed;
};
static int clamp(int x, int min, int max);
static int ms_to_timer(int ms);
-static int ms_to_timer_remainder(int ms);
static int timer_to_ms(int timer);
static void stp_start_timer(struct stp_timer *, int value);
static void stp_stop_timer(struct stp_timer *);
* are called too frequently. */
ms = clamp(ms, 0, INT_MAX - 1000) + stp->elapsed_remainder;
elapsed = ms_to_timer(ms);
- stp->elapsed_remainder = ms_to_timer_remainder(ms);
+ stp->elapsed_remainder = ms - timer_to_ms(elapsed);
if (!elapsed) {
return;
}
if (bpdu_size < sizeof(struct stp_bpdu_header)) {
VLOG_WARN("%s: received runt %zu-byte BPDU", stp->name, bpdu_size);
+ p->error_count++;
return;
}
if (header->protocol_id != htons(STP_PROTOCOL_ID)) {
VLOG_WARN("%s: received BPDU with unexpected protocol ID %"PRIu16,
stp->name, ntohs(header->protocol_id));
+ p->error_count++;
return;
}
if (header->protocol_version != STP_PROTOCOL_VERSION) {
if (bpdu_size < sizeof(struct stp_config_bpdu)) {
VLOG_WARN("%s: received config BPDU with invalid size %zu",
stp->name, bpdu_size);
+ p->error_count++;
return;
}
stp_received_config_bpdu(stp, p, bpdu);
if (bpdu_size != sizeof(struct stp_tcn_bpdu)) {
VLOG_WARN("%s: received TCN BPDU with invalid size %zu",
stp->name, bpdu_size);
+ p->error_count++;
return;
}
stp_received_tcn_bpdu(stp, p);
default:
VLOG_WARN("%s: received BPDU of unexpected type %"PRIu8,
stp->name, header->bpdu_type);
+ p->error_count++;
return;
}
+ p->rx_count++;
}
/* Returns the STP entity in which 'p' is nested. */
}
}
+/* Retrieves BPDU transmit and receive counts for 'p'. */
+void stp_port_get_counts(const struct stp_port *p,
+ int *tx_count, int *rx_count, int *error_count)
+{
+ *tx_count = p->tx_count;
+ *rx_count = p->rx_count;
+ *error_count = p->error_count;
+}
+
/* Disables STP on port 'p'. */
void
stp_port_disable(struct stp_port *p)
stp_stop_timer(&p->message_age_timer);
stp_stop_timer(&p->forward_delay_timer);
stp_stop_timer(&p->hold_timer);
+ p->tx_count = p->rx_count = p->error_count = 0;
}
static void
return ms * 0x100 / 1000;
}
-/* Returns the number of leftover milliseconds when 'ms' is converted to STP
- * timer ticks. */
-static int
-ms_to_timer_remainder(int ms)
-{
- return ms * 0x100 % 1000;
-}
-
/* Returns the number of whole milliseconds in 'timer' STP timer ticks. There
* are 256 STP timer ticks per second. */
static int
llc->llc_cntl = STP_LLC_CNTL;
p->stp->send_bpdu(pkt, stp_port_no(p), p->stp->aux);
+ p->tx_count++;
}