ofproto: Inline trivial functions.
[sliver-openvswitch.git] / lib / stp.c
index 6e1efd0..dbe48e8 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <inttypes.h>
 #include <stdlib.h>
 #include "byte-order.h"
+#include "connectivity.h"
 #include "ofpbuf.h"
 #include "packets.h"
+#include "seq.h"
 #include "unixctl.h"
 #include "util.h"
 #include "vlog.h"
@@ -141,7 +143,7 @@ struct stp {
     void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux);
     void *aux;
 
-    atomic_int ref_cnt;
+    struct ovs_refcount ref_cnt;
 };
 
 static struct ovs_mutex mutex;
@@ -304,7 +306,7 @@ stp_create(const char *name, stp_identifier bridge_id,
         p->path_cost = 19;      /* Recommended default for 100 Mb/s link. */
         stp_initialize_port(p, STP_DISABLED);
     }
-    atomic_init(&stp->ref_cnt, 1);
+    ovs_refcount_init(&stp->ref_cnt);
 
     list_push_back(all_stps, &stp->node);
     ovs_mutex_unlock(&mutex);
@@ -316,9 +318,7 @@ stp_ref(const struct stp *stp_)
 {
     struct stp *stp = CONST_CAST(struct stp *, stp_);
     if (stp) {
-        int orig;
-        atomic_add(&stp->ref_cnt, 1, &orig);
-        ovs_assert(orig > 0);
+        ovs_refcount_ref(&stp->ref_cnt);
     }
     return stp;
 }
@@ -327,15 +327,7 @@ stp_ref(const struct stp *stp_)
 void
 stp_unref(struct stp *stp)
 {
-    int orig;
-
-    if (!stp) {
-        return;
-    }
-
-    atomic_sub(&stp->ref_cnt, 1, &orig);
-    ovs_assert(orig > 0);
-    if (orig == 1) {
+    if (stp && ovs_refcount_unref(&stp->ref_cnt) == 1) {
         ovs_mutex_lock(&mutex);
         list_remove(&stp->node);
         ovs_mutex_unlock(&mutex);
@@ -666,7 +658,7 @@ stp_state_name(enum stp_state state)
     case STP_BLOCKING:
         return "blocking";
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -692,6 +684,15 @@ stp_learn_in_state(enum stp_state state)
     return (state & (STP_DISABLED | STP_LEARNING | STP_FORWARDING)) != 0;
 }
 
+/* Returns true if 'state' is one in which rx&tx bpdu should be done on
+ * on a port, false otherwise. */
+bool
+stp_listen_in_state(enum stp_state state)
+{
+    return (state &
+            (STP_LISTENING | STP_LEARNING | STP_FORWARDING)) != 0;
+}
+
 /* Returns the name for the given 'role' (for use in debugging and log
  * messages). */
 const char *
@@ -707,7 +708,7 @@ stp_role_name(enum stp_role role)
     case STP_ROLE_DISABLED:
         return "disabled";
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -727,7 +728,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);
+        VLOG_WARN("%s: received runt %"PRIuSIZE"-byte BPDU", stp->name, bpdu_size);
         p->error_count++;
         goto out;
     }
@@ -747,7 +748,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
     switch (header->bpdu_type) {
     case STP_TYPE_CONFIG:
         if (bpdu_size < sizeof(struct stp_config_bpdu)) {
-            VLOG_WARN("%s: received config BPDU with invalid size %zu",
+            VLOG_WARN("%s: received config BPDU with invalid size %"PRIuSIZE,
                       stp->name, bpdu_size);
             p->error_count++;
             goto out;
@@ -757,7 +758,7 @@ stp_received_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
 
     case STP_TYPE_TCN:
         if (bpdu_size != sizeof(struct stp_tcn_bpdu)) {
-            VLOG_WARN("%s: received TCN BPDU with invalid size %zu",
+            VLOG_WARN("%s: received TCN BPDU with invalid size %"PRIuSIZE,
                       stp->name, bpdu_size);
             p->error_count++;
             goto out;
@@ -1127,6 +1128,7 @@ stp_configuration_update(struct stp *stp) OVS_REQUIRES(mutex)
 {
     stp_root_selection(stp);
     stp_designated_port_selection(stp);
+    seq_change(connectivity_seq_get());
 }
 
 static bool
@@ -1257,6 +1259,7 @@ stp_set_port_state(struct stp_port *p, enum stp_state state)
         if (p < p->stp->first_changed_port) {
             p->stp->first_changed_port = p;
         }
+        seq_change(connectivity_seq_get());
     }
     p->state = state;
 }
@@ -1275,6 +1278,7 @@ stp_topology_change_detection(struct stp *stp) OVS_REQUIRES(mutex)
     }
     stp->fdb_needs_flush = true;
     stp->topology_change_detected = true;
+    seq_change(connectivity_seq_get());
     VLOG_INFO_RL(&rl, "%s: detected topology change.", stp->name);
 }
 
@@ -1531,14 +1535,15 @@ stp_send_bpdu(struct stp_port *p, const void *bpdu, size_t bpdu_size)
 
     /* Skeleton. */
     pkt = ofpbuf_new(ETH_HEADER_LEN + LLC_HEADER_LEN + bpdu_size);
-    pkt->l2 = eth = ofpbuf_put_zeros(pkt, sizeof *eth);
+    eth = ofpbuf_put_zeros(pkt, sizeof *eth);
     llc = ofpbuf_put_zeros(pkt, sizeof *llc);
-    pkt->l3 = ofpbuf_put(pkt, bpdu, bpdu_size);
+    ofpbuf_set_frame(pkt, eth);
+    ofpbuf_set_l3(pkt, ofpbuf_put(pkt, bpdu, bpdu_size));
 
     /* 802.2 header. */
     memcpy(eth->eth_dst, eth_addr_stp, ETH_ADDR_LEN);
     /* p->stp->send_bpdu() must fill in source address. */
-    eth->eth_type = htons(pkt->size - ETH_HEADER_LEN);
+    eth->eth_type = htons(ofpbuf_size(pkt) - ETH_HEADER_LEN);
 
     /* LLC header. */
     llc->llc_dsap = STP_LLC_DSAP;