X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fbond.c;h=a2105ca3f4d277e7838235d925922d2af049eaee;hb=58cb487b92ab039bd0c3ce5e4b4b5c7063c44476;hp=bb5d49968b70186e389ff4b4cacff4c7aa0d9a21;hpb=7b9f1974f42d63693676d2611f9276fb8227e071;p=sliver-openvswitch.git diff --git a/lib/bond.c b/lib/bond.c index bb5d49968..a2105ca3f 100644 --- a/lib/bond.c +++ b/lib/bond.c @@ -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); }