rhel, xenserver: Create /var/log/openvswitch directory.
[sliver-openvswitch.git] / lib / lacp.c
index 8bc115d..64cdbe7 100644 (file)
@@ -100,6 +100,8 @@ struct lacp {
     bool fast;               /* True if using fast probe interval. */
     bool negotiated;         /* True if LACP negotiations were successful. */
     bool update;             /* True if lacp_update() needs to be called. */
+
+    int ref_cnt;
 };
 
 struct slave {
@@ -197,14 +199,31 @@ lacp_create(void)
     lacp = xzalloc(sizeof *lacp);
     hmap_init(&lacp->slaves);
     list_push_back(&all_lacps, &lacp->node);
+    lacp->ref_cnt = 1;
+    return lacp;
+}
+
+struct lacp *
+lacp_ref(const struct lacp *lacp_)
+{
+    struct lacp *lacp = CONST_CAST(struct lacp *, lacp_);
+    if (lacp) {
+        ovs_assert(lacp->ref_cnt > 0);
+        lacp->ref_cnt++;
+    }
     return lacp;
 }
 
 /* Destroys 'lacp' and its slaves. Does nothing if 'lacp' is NULL. */
 void
-lacp_destroy(struct lacp *lacp)
+lacp_unref(struct lacp *lacp)
 {
-    if (lacp) {
+    if (!lacp) {
+        return;
+    }
+
+    ovs_assert(lacp->ref_cnt > 0);
+    if (!--lacp->ref_cnt) {
         struct slave *slave, *next;
 
         HMAP_FOR_EACH_SAFE (slave, next, node, &lacp->slaves) {
@@ -260,6 +279,10 @@ lacp_process_packet(struct lacp *lacp, const void *slave_,
     const struct lacp_pdu *pdu;
     long long int tx_rate;
 
+    if (!slave) {
+        return;
+    }
+
     pdu = parse_lacp_packet(packet);
     if (!pdu) {
         VLOG_WARN_RL(&rl, "%s: received an unparsable LACP PDU.", lacp->name);
@@ -355,6 +378,10 @@ lacp_slave_carrier_changed(const struct lacp *lacp, const void *slave_)
     if (lacp) {
         struct slave *slave = slave_lookup(lacp, slave_);
 
+        if (!slave) {
+            return;
+        }
+
         if (slave->status == LACP_CURRENT || slave->lacp->active) {
             slave_set_expired(slave);
         }
@@ -376,7 +403,8 @@ bool
 lacp_slave_may_enable(const struct lacp *lacp, const void *slave_)
 {
     if (lacp) {
-        return slave_may_enable__(slave_lookup(lacp, slave_));
+        struct slave *slave = slave_lookup(lacp, slave_);
+        return slave ? slave_may_enable__(slave) : false;
     } else {
         return true;
     }
@@ -388,7 +416,8 @@ lacp_slave_may_enable(const struct lacp *lacp, const void *slave_)
 bool
 lacp_slave_is_current(const struct lacp *lacp, const void *slave_)
 {
-    return slave_lookup(lacp, slave_)->status != LACP_DEFAULTED;
+    struct slave *slave = slave_lookup(lacp, slave_);
+    return slave ? slave->status != LACP_DEFAULTED : false;
 }
 
 /* This function should be called periodically to update 'lacp'. */