xenserver: Restart ovs-xapi-sync on kmod reload.
[sliver-openvswitch.git] / lib / stp.c
index 94b9a4b..3e9a5b6 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -93,6 +93,10 @@ struct stp_port {
     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;
 };
 
@@ -188,7 +192,6 @@ static void stp_update_bridge_timers(struct stp *);
 
 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 *);
@@ -277,7 +280,7 @@ stp_tick(struct stp *stp, int ms)
      * 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;
     }
@@ -562,6 +565,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
 
     if (bpdu_size < sizeof(struct stp_bpdu_header)) {
         VLOG_WARN("%s: received runt %zu-byte BPDU", stp->name, bpdu_size);
+        p->error_count++;
         return;
     }
 
@@ -569,6 +573,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
     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) {
@@ -581,6 +586,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
         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);
@@ -590,6 +596,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
         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);
@@ -598,8 +605,10 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
     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. */
@@ -667,6 +676,15 @@ stp_port_get_role(const struct stp_port *p)
     }
 }
 
+/* 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)
@@ -1185,6 +1203,7 @@ stp_initialize_port(struct stp_port *p, enum stp_state state)
     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
@@ -1233,14 +1252,6 @@ ms_to_timer(int ms)
     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
@@ -1299,4 +1310,5 @@ stp_send_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
     llc->llc_cntl = STP_LLC_CNTL;
 
     p->stp->send_bpdu(pkt, stp_port_no(p), p->stp->aux);
+    p->tx_count++;
 }