Global replace of Nicira Networks.
[sliver-openvswitch.git] / lib / bond.c
index 50a1d5d..cffdae2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -246,7 +246,11 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s)
 
     bond->updelay = s->up_delay;
     bond->downdelay = s->down_delay;
-    bond->rebalance_interval = s->rebalance_interval;
+
+    if (bond->rebalance_interval != s->rebalance_interval) {
+        bond->rebalance_interval = s->rebalance_interval;
+        revalidate = true;
+    }
 
     if (bond->balance != s->balance) {
         bond->balance = s->balance;
@@ -648,7 +652,8 @@ bond_choose_output_slave(struct bond *bond, const struct flow *flow,
 static bool
 bond_is_balanced(const struct bond *bond)
 {
-    return bond->balance == BM_SLB || bond->balance == BM_TCP;
+    return bond->rebalance_interval
+        && (bond->balance == BM_SLB || bond->balance == BM_TCP);
 }
 
 /* Notifies 'bond' that 'n_bytes' bytes were sent in 'flow' within 'vlan'. */
@@ -936,7 +941,7 @@ bond_unixctl_list(struct unixctl_conn *conn,
         }
         ds_put_char(&ds, '\n');
     }
-    unixctl_command_reply(conn, 200, ds_cstr(&ds));
+    unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
 }
 
@@ -1037,7 +1042,7 @@ bond_unixctl_show(struct unixctl_conn *conn,
         const struct bond *bond = bond_find(argv[1]);
 
         if (!bond) {
-            unixctl_command_reply(conn, 501, "no such bond");
+            unixctl_command_reply_error(conn, "no such bond");
             return;
         }
         bond_print_details(&ds, bond);
@@ -1049,7 +1054,7 @@ bond_unixctl_show(struct unixctl_conn *conn,
         }
     }
 
-    unixctl_command_reply(conn, 200, ds_cstr(&ds));
+    unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
 }
 
@@ -1068,30 +1073,30 @@ bond_unixctl_migrate(struct unixctl_conn *conn,
 
     bond = bond_find(bond_s);
     if (!bond) {
-        unixctl_command_reply(conn, 501, "no such bond");
+        unixctl_command_reply_error(conn, "no such bond");
         return;
     }
 
     if (bond->balance != BM_SLB) {
-        unixctl_command_reply(conn, 501, "not an SLB bond");
+        unixctl_command_reply_error(conn, "not an SLB bond");
         return;
     }
 
     if (strspn(hash_s, "0123456789") == strlen(hash_s)) {
         hash = atoi(hash_s) & BOND_MASK;
     } else {
-        unixctl_command_reply(conn, 501, "bad hash");
+        unixctl_command_reply_error(conn, "bad hash");
         return;
     }
 
     slave = bond_lookup_slave(bond, slave_s);
     if (!slave) {
-        unixctl_command_reply(conn, 501, "no such slave");
+        unixctl_command_reply_error(conn, "no such slave");
         return;
     }
 
     if (!slave->enabled) {
-        unixctl_command_reply(conn, 501, "cannot migrate to disabled slave");
+        unixctl_command_reply_error(conn, "cannot migrate to disabled slave");
         return;
     }
 
@@ -1099,7 +1104,7 @@ bond_unixctl_migrate(struct unixctl_conn *conn,
     tag_set_add(&bond->unixctl_tags, entry->tag);
     entry->slave = slave;
     entry->tag = tag_create_random();
-    unixctl_command_reply(conn, 200, "migrated");
+    unixctl_command_reply(conn, "migrated");
 }
 
 static void
@@ -1114,18 +1119,18 @@ bond_unixctl_set_active_slave(struct unixctl_conn *conn,
 
     bond = bond_find(bond_s);
     if (!bond) {
-        unixctl_command_reply(conn, 501, "no such bond");
+        unixctl_command_reply_error(conn, "no such bond");
         return;
     }
 
     slave = bond_lookup_slave(bond, slave_s);
     if (!slave) {
-        unixctl_command_reply(conn, 501, "no such slave");
+        unixctl_command_reply_error(conn, "no such slave");
         return;
     }
 
     if (!slave->enabled) {
-        unixctl_command_reply(conn, 501, "cannot make disabled slave active");
+        unixctl_command_reply_error(conn, "cannot make disabled slave active");
         return;
     }
 
@@ -1136,9 +1141,9 @@ bond_unixctl_set_active_slave(struct unixctl_conn *conn,
         VLOG_INFO("bond %s: active interface is now %s",
                   bond->name, slave->name);
         bond->send_learning_packets = true;
-        unixctl_command_reply(conn, 200, "done");
+        unixctl_command_reply(conn, "done");
     } else {
-        unixctl_command_reply(conn, 200, "no change");
+        unixctl_command_reply(conn, "no change");
     }
 }
 
@@ -1152,18 +1157,18 @@ enable_slave(struct unixctl_conn *conn, const char *argv[], bool enable)
 
     bond = bond_find(bond_s);
     if (!bond) {
-        unixctl_command_reply(conn, 501, "no such bond");
+        unixctl_command_reply_error(conn, "no such bond");
         return;
     }
 
     slave = bond_lookup_slave(bond, slave_s);
     if (!slave) {
-        unixctl_command_reply(conn, 501, "no such slave");
+        unixctl_command_reply_error(conn, "no such slave");
         return;
     }
 
     bond_enable_slave(slave, enable, &bond->unixctl_tags);
-    unixctl_command_reply(conn, 501, enable ? "enabled" : "disabled");
+    unixctl_command_reply(conn, enable ? "enabled" : "disabled");
 }
 
 static void
@@ -1197,7 +1202,7 @@ bond_unixctl_hash(struct unixctl_conn *conn, int argc, const char *argv[],
 
     if (vlan_s) {
         if (sscanf(vlan_s, "%u", &vlan) != 1) {
-            unixctl_command_reply(conn, 501, "invalid vlan");
+            unixctl_command_reply_error(conn, "invalid vlan");
             return;
         }
     } else {
@@ -1206,7 +1211,7 @@ bond_unixctl_hash(struct unixctl_conn *conn, int argc, const char *argv[],
 
     if (basis_s) {
         if (sscanf(basis_s, "%"PRIu32, &basis) != 1) {
-            unixctl_command_reply(conn, 501, "invalid basis");
+            unixctl_command_reply_error(conn, "invalid basis");
             return;
         }
     } else {
@@ -1218,10 +1223,10 @@ bond_unixctl_hash(struct unixctl_conn *conn, int argc, const char *argv[],
         hash = bond_hash_src(mac, vlan, basis) & BOND_MASK;
 
         hash_cstr = xasprintf("%u", hash);
-        unixctl_command_reply(conn, 200, hash_cstr);
+        unixctl_command_reply(conn, hash_cstr);
         free(hash_cstr);
     } else {
-        unixctl_command_reply(conn, 501, "invalid mac");
+        unixctl_command_reply_error(conn, "invalid mac");
     }
 }
 
@@ -1376,15 +1381,13 @@ lookup_bond_entry(const struct bond *bond, const struct flow *flow,
  * more complex implementations and require the use of memory.  This may need
  * to be reimplemented if it becomes a performance bottleneck. */
 static struct bond_slave *
-choose_stb_slave(const struct bond *bond, const struct flow *flow,
-                 uint16_t vlan)
+choose_stb_slave(const struct bond *bond, uint32_t flow_hash)
 {
     struct bond_slave *best, *slave;
-    uint32_t best_hash, flow_hash;
+    uint32_t best_hash;
 
     best = NULL;
     best_hash = 0;
-    flow_hash = bond_hash_tcp(flow, vlan, bond->basis);
     HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) {
         if (slave->enabled) {
             uint32_t hash;
@@ -1417,7 +1420,7 @@ choose_output_slave(const struct bond *bond, const struct flow *flow,
         return bond->active_slave;
 
     case BM_STABLE:
-        return choose_stb_slave(bond, flow, vlan);
+        return choose_stb_slave(bond, bond_hash_tcp(flow, vlan, bond->basis));
 
     case BM_TCP:
         if (bond->lacp_status != LACP_NEGOTIATED) {
@@ -1426,6 +1429,9 @@ choose_output_slave(const struct bond *bond, const struct flow *flow,
         }
         /* Fall Through. */
     case BM_SLB:
+        if (!bond_is_balanced(bond)) {
+            return choose_stb_slave(bond, bond_hash(bond, flow, vlan));
+        }
         e = lookup_bond_entry(bond, flow, vlan);
         if (!e->slave || !e->slave->enabled) {
             e->slave = CONTAINER_OF(hmap_random_node(&bond->slaves),