datapath: remove unused version.h includes
[sliver-openvswitch.git] / lib / bond.c
index bb5d499..a2105ca 100644 (file)
@@ -32,6 +32,7 @@
 #include "ofpbuf.h"
 #include "packets.h"
 #include "poll-loop.h"
+#include "shash.h"
 #include "tag.h"
 #include "timeval.h"
 #include "unixctl.h"
@@ -406,7 +407,10 @@ bond_run(struct bond *bond, struct tag_set *tags, bool lacp_negotiated)
     struct bond_slave *slave;
     bool is_tcp_hash = bond_is_tcp_hash(bond);
 
-    bond->lacp_negotiated = lacp_negotiated;
+    if (bond->lacp_negotiated != lacp_negotiated) {
+        bond->lacp_negotiated = lacp_negotiated;
+        bond->bond_revalidate = true;
+    }
 
     /* Enable slaves based on link status and LACP feedback. */
     HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) {
@@ -906,7 +910,8 @@ bond_lookup_slave(struct bond *bond, const char *slave_name)
 
 static void
 bond_unixctl_list(struct unixctl_conn *conn,
-                  const char *args OVS_UNUSED, void *aux OVS_UNUSED)
+                  int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
+                  void *aux OVS_UNUSED)
 {
     struct ds ds = DS_EMPTY_INITIALIZER;
     const struct bond *bond;
@@ -934,56 +939,58 @@ bond_unixctl_list(struct unixctl_conn *conn,
 }
 
 static void
-bond_unixctl_show(struct unixctl_conn *conn,
-                  const char *args, void *aux OVS_UNUSED)
+bond_print_details(struct ds *ds, const struct bond *bond)
 {
-    struct ds ds = DS_EMPTY_INITIALIZER;
+    struct shash slave_shash = SHASH_INITIALIZER(&slave_shash);
+    const struct shash_node **sorted_slaves = NULL;
     const struct bond_slave *slave;
-    const struct bond *bond;
-
-    bond = bond_find(args);
-    if (!bond) {
-        unixctl_command_reply(conn, 501, "no such bond");
-        return;
-    }
+    int i;
 
-    ds_put_format(&ds, "bond_mode: %s\n",
+    ds_put_format(ds, "---- %s ----\n", bond->name);
+    ds_put_format(ds, "bond_mode: %s\n",
                   bond_mode_to_string(bond->balance));
 
     if (bond->balance != BM_AB) {
-        ds_put_format(&ds, "bond-hash-algorithm: %s\n",
+        ds_put_format(ds, "bond-hash-algorithm: %s\n",
                       bond_is_tcp_hash(bond) ? "balance-tcp" : "balance-slb");
     }
 
-    ds_put_format(&ds, "bond-hash-basis: %"PRIu32"\n", bond->basis);
+    ds_put_format(ds, "bond-hash-basis: %"PRIu32"\n", bond->basis);
 
-    ds_put_format(&ds, "updelay: %d ms\n", bond->updelay);
-    ds_put_format(&ds, "downdelay: %d ms\n", bond->downdelay);
+    ds_put_format(ds, "updelay: %d ms\n", bond->updelay);
+    ds_put_format(ds, "downdelay: %d ms\n", bond->downdelay);
 
     if (bond_is_balanced(bond)) {
-        ds_put_format(&ds, "next rebalance: %lld ms\n",
+        ds_put_format(ds, "next rebalance: %lld ms\n",
                       bond->next_rebalance - time_msec());
     }
 
-    ds_put_format(&ds, "lacp_negotiated: %s\n",
+    ds_put_format(ds, "lacp_negotiated: %s\n",
                   bond->lacp_negotiated ? "true" : "false");
 
     HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) {
+        shash_add(&slave_shash, slave->name, slave);
+    }
+    sorted_slaves = shash_sort(&slave_shash);
+
+    for (i = 0; i < shash_count(&slave_shash); i++) {
         struct bond_entry *be;
 
+        slave = sorted_slaves[i]->data;
+
         /* Basic info. */
-        ds_put_format(&ds, "\nslave %s: %s\n",
+        ds_put_format(ds, "\nslave %s: %s\n",
                       slave->name, slave->enabled ? "enabled" : "disabled");
         if (slave == bond->active_slave) {
-            ds_put_cstr(&ds, "\tactive slave\n");
+            ds_put_cstr(ds, "\tactive slave\n");
         }
         if (slave->delay_expires != LLONG_MAX) {
-            ds_put_format(&ds, "\t%s expires in %lld ms\n",
+            ds_put_format(ds, "\t%s expires in %lld ms\n",
                           slave->enabled ? "downdelay" : "updelay",
                           slave->delay_expires - time_msec());
         }
 
-        ds_put_format(&ds, "\tmay_enable: %s\n",
+        ds_put_format(ds, "\tmay_enable: %s\n",
                       slave->may_enable ? "true" : "false");
 
         if (!bond_is_balanced(bond)) {
@@ -998,37 +1005,57 @@ bond_unixctl_show(struct unixctl_conn *conn,
                 continue;
             }
 
-            ds_put_format(&ds, "\thash %d: %"PRIu64" kB load\n",
+            ds_put_format(ds, "\thash %d: %"PRIu64" kB load\n",
                           hash, be->tx_bytes / 1024);
 
             /* XXX How can we list the MACs assigned to hashes of SLB bonds? */
         }
     }
+    shash_destroy(&slave_shash);
+    free(sorted_slaves);
+    ds_put_cstr(ds, "\n");
+}
+
+static void
+bond_unixctl_show(struct unixctl_conn *conn,
+                  int argc, const char *argv[],
+                  void *aux OVS_UNUSED)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+
+    if (argc > 1) {
+        const struct bond *bond = bond_find(argv[1]);
+
+        if (!bond) {
+            unixctl_command_reply(conn, 501, "no such bond");
+            return;
+        }
+        bond_print_details(&ds, bond);
+    } else {
+        const struct bond *bond;
+
+        HMAP_FOR_EACH (bond, hmap_node, &all_bonds) {
+            bond_print_details(&ds, bond);
+        }
+    }
+
     unixctl_command_reply(conn, 200, ds_cstr(&ds));
     ds_destroy(&ds);
 }
 
 static void
-bond_unixctl_migrate(struct unixctl_conn *conn, const char *args_,
+bond_unixctl_migrate(struct unixctl_conn *conn,
+                     int argc OVS_UNUSED, const char *argv[],
                      void *aux OVS_UNUSED)
 {
-    char *args = (char *) args_;
-    char *save_ptr = NULL;
-    char *bond_s, *hash_s, *slave_s;
+    const char *bond_s = argv[1];
+    const char *hash_s = argv[2];
+    const char *slave_s = argv[3];
     struct bond *bond;
     struct bond_slave *slave;
     struct bond_entry *entry;
     int hash;
 
-    bond_s = strtok_r(args, " ", &save_ptr);
-    hash_s = strtok_r(NULL, " ", &save_ptr);
-    slave_s = strtok_r(NULL, " ", &save_ptr);
-    if (!slave_s) {
-        unixctl_command_reply(conn, 501,
-                              "usage: bond/migrate BOND HASH SLAVE");
-        return;
-    }
-
     bond = bond_find(bond_s);
     if (!bond) {
         unixctl_command_reply(conn, 501, "no such bond");
@@ -1066,23 +1093,15 @@ bond_unixctl_migrate(struct unixctl_conn *conn, const char *args_,
 }
 
 static void
-bond_unixctl_set_active_slave(struct unixctl_conn *conn, const char *args_,
+bond_unixctl_set_active_slave(struct unixctl_conn *conn,
+                              int argc OVS_UNUSED, const char *argv[],
                               void *aux OVS_UNUSED)
 {
-    char *args = (char *) args_;
-    char *save_ptr = NULL;
-    char *bond_s, *slave_s;
+    const char *bond_s = argv[1];
+    const char *slave_s = argv[2];
     struct bond *bond;
     struct bond_slave *slave;
 
-    bond_s = strtok_r(args, " ", &save_ptr);
-    slave_s = strtok_r(NULL, " ", &save_ptr);
-    if (!slave_s) {
-        unixctl_command_reply(conn, 501,
-                              "usage: bond/set-active-slave BOND SLAVE");
-        return;
-    }
-
     bond = bond_find(bond_s);
     if (!bond) {
         unixctl_command_reply(conn, 501, "no such bond");
@@ -1114,24 +1133,13 @@ bond_unixctl_set_active_slave(struct unixctl_conn *conn, const char *args_,
 }
 
 static void
-enable_slave(struct unixctl_conn *conn, const char *args_, bool enable)
+enable_slave(struct unixctl_conn *conn, const char *argv[], bool enable)
 {
-    char *args = (char *) args_;
-    char *save_ptr = NULL;
-    char *bond_s, *slave_s;
+    const char *bond_s = argv[1];
+    const char *slave_s = argv[2];
     struct bond *bond;
     struct bond_slave *slave;
 
-    bond_s = strtok_r(args, " ", &save_ptr);
-    slave_s = strtok_r(NULL, " ", &save_ptr);
-    if (!slave_s) {
-        char *usage = xasprintf("usage: bond/%s-slave BOND SLAVE",
-                                enable ? "enable" : "disable");
-        unixctl_command_reply(conn, 501, usage);
-        free(usage);
-        return;
-    }
-
     bond = bond_find(bond_s);
     if (!bond) {
         unixctl_command_reply(conn, 501, "no such bond");
@@ -1149,35 +1157,33 @@ enable_slave(struct unixctl_conn *conn, const char *args_, bool enable)
 }
 
 static void
-bond_unixctl_enable_slave(struct unixctl_conn *conn, const char *args,
+bond_unixctl_enable_slave(struct unixctl_conn *conn,
+                          int argc OVS_UNUSED, const char *argv[],
                           void *aux OVS_UNUSED)
 {
-    enable_slave(conn, args, true);
+    enable_slave(conn, argv, true);
 }
 
 static void
-bond_unixctl_disable_slave(struct unixctl_conn *conn, const char *args,
+bond_unixctl_disable_slave(struct unixctl_conn *conn,
+                           int argc OVS_UNUSED, const char *argv[],
                            void *aux OVS_UNUSED)
 {
-    enable_slave(conn, args, false);
+    enable_slave(conn, argv, false);
 }
 
 static void
-bond_unixctl_hash(struct unixctl_conn *conn, const char *args_,
+bond_unixctl_hash(struct unixctl_conn *conn, int argc, const char *argv[],
                   void *aux OVS_UNUSED)
 {
-    char *args = (char *) args_;
+    const char *mac_s = argv[1];
+    const char *vlan_s = argc > 2 ? argv[2] : NULL;
+    const char *basis_s = argc > 3 ? argv[3] : NULL;
     uint8_t mac[ETH_ADDR_LEN];
     uint8_t hash;
     char *hash_cstr;
     unsigned int vlan;
     uint32_t basis;
-    char *mac_s, *vlan_s, *basis_s;
-    char *save_ptr = NULL;
-
-    mac_s  = strtok_r(args, " ", &save_ptr);
-    vlan_s = strtok_r(NULL, " ", &save_ptr);
-    basis_s = strtok_r(NULL, " ", &save_ptr);
 
     if (vlan_s) {
         if (sscanf(vlan_s, "%u", &vlan) != 1) {
@@ -1212,17 +1218,18 @@ bond_unixctl_hash(struct unixctl_conn *conn, const char *args_,
 void
 bond_init(void)
 {
-    unixctl_command_register("bond/list", "", bond_unixctl_list, NULL);
-    unixctl_command_register("bond/show", "port", bond_unixctl_show, NULL);
-    unixctl_command_register("bond/migrate", "port hash slave",
+    unixctl_command_register("bond/list", "", 0, 0, bond_unixctl_list, NULL);
+    unixctl_command_register("bond/show", "[port]", 0, 1, bond_unixctl_show,
+                             NULL);
+    unixctl_command_register("bond/migrate", "port hash slave", 3, 3,
                              bond_unixctl_migrate, NULL);
-    unixctl_command_register("bond/set-active-slave", "port slave",
+    unixctl_command_register("bond/set-active-slave", "port slave", 2, 2,
                              bond_unixctl_set_active_slave, NULL);
-    unixctl_command_register("bond/enable-slave", "port slave",
+    unixctl_command_register("bond/enable-slave", "port slave", 2, 2,
                              bond_unixctl_enable_slave, NULL);
-    unixctl_command_register("bond/disable-slave", "port slave",
+    unixctl_command_register("bond/disable-slave", "port slave", 2, 2,
                              bond_unixctl_disable_slave, NULL);
-    unixctl_command_register("bond/hash", "mac [vlan] [basis]",
+    unixctl_command_register("bond/hash", "mac [vlan] [basis]", 1, 3,
                              bond_unixctl_hash, NULL);
 }
 \f