X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Flacp.c;h=9eac4fe9f47ef5beba4766ec6b9e2960ed62cf17;hb=906087ee33bdf5792df192048944dfe42496e1a9;hp=edf7f6792043a01b1e313ee2c07306052d889955;hpb=2204c61a4f85b14685f6dca6bbfac8adac6e2810;p=sliver-openvswitch.git diff --git a/lib/lacp.c b/lib/lacp.c index edf7f6792..9eac4fe9f 100644 --- a/lib/lacp.c +++ b/lib/lacp.c @@ -136,8 +136,7 @@ static bool slave_may_tx(const struct slave *); static struct slave *slave_lookup(const struct lacp *, const void *slave); static bool info_tx_equal(struct lacp_info *, struct lacp_info *); -static void lacp_unixctl_show(struct unixctl_conn *, const char *args, - void *aux); +static unixctl_cb_func lacp_unixctl_show; /* Populates 'pdu' with a LACP PDU comprised of 'actor' and 'partner'. */ static void @@ -188,7 +187,8 @@ parse_lacp_packet(const struct ofpbuf *b) void lacp_init(void) { - unixctl_command_register("lacp/show", "[port]", lacp_unixctl_show, NULL); + unixctl_command_register("lacp/show", "[port]", 0, 1, + lacp_unixctl_show, NULL); } /* Creates a LACP object. */ @@ -301,12 +301,17 @@ lacp_process_packet(struct lacp *lacp, const void *slave_, } } -/* Returns true if 'lacp' has successfully negotiated with its partner. False - * if 'lacp' is NULL. */ -bool -lacp_negotiated(const struct lacp *lacp) +/* Returns the lacp_status of the given 'lacp' object (which may be NULL). */ +enum lacp_status +lacp_status(const struct lacp *lacp) { - return lacp ? lacp->negotiated : false; + if (!lacp) { + return LACP_DISABLED; + } else if (lacp->negotiated) { + return LACP_NEGOTIATED; + } else { + return LACP_CONFIGURED; + } } /* Registers 'slave_' as subordinate to 'lacp'. This should be called at least @@ -363,14 +368,16 @@ lacp_slave_unregister(struct lacp *lacp, const void *slave_) } /* This function should be called whenever the carrier status of 'slave_' has - * changed. */ + * changed. If 'lacp' is null, this function has no effect.*/ void lacp_slave_carrier_changed(const struct lacp *lacp, const void *slave_) { - struct slave *slave = slave_lookup(lacp, slave_); + if (lacp) { + struct slave *slave = slave_lookup(lacp, slave_); - if (slave->status == LACP_CURRENT || slave->lacp->active) { - slave_set_expired(slave); + if (slave->status == LACP_CURRENT || slave->lacp->active) { + slave_set_expired(slave); + } } } @@ -384,12 +391,8 @@ lacp_slave_may_enable(const struct lacp *lacp, const void *slave_) struct slave *slave = slave_lookup(lacp, slave_); /* The slave may be enabled if it's attached to an aggregator and its - * partner is synchronized. The only exception is defaulted slaves. - * They are not required to have synchronized partners because they - * have no partners at all. They will only be attached if negotiations - * failed on all slaves in the bond. */ - return slave->attached && (slave->partner.state & LACP_STATE_SYNC - || slave->status == LACP_DEFAULTED); + * partner is synchronized.*/ + return slave->attached && (slave->partner.state & LACP_STATE_SYNC); } else { return true; } @@ -504,14 +507,13 @@ lacp_update_attached(struct lacp *lacp) HMAP_FOR_EACH (slave, node, &lacp->slaves) { struct lacp_info pri; - slave->attached = true; + slave->attached = false; /* XXX: In the future allow users to configure the expected system ID. * For now just special case loopback. */ if (eth_addr_equals(slave->partner.sys_id, slave->lacp->sys_id)) { VLOG_WARN_RL(&rl, "slave %s: Loopback detected. Slave is " "connected to its own bond", slave->name); - slave->attached = false; continue; } @@ -519,6 +521,7 @@ lacp_update_attached(struct lacp *lacp) continue; } + slave->attached = true; slave_get_priority(slave, &pri); if (!lead || memcmp(&pri, &lead_pri, sizeof pri) < 0) { @@ -531,8 +534,7 @@ lacp_update_attached(struct lacp *lacp) if (lead) { HMAP_FOR_EACH (slave, node, &lacp->slaves) { - if (slave->status == LACP_DEFAULTED - || lead->partner.key != slave->partner.key + if (lead->partner.key != slave->partner.key || !eth_addr_equals(lead->partner.sys_id, slave->partner.sys_id)) { slave->attached = false; @@ -869,16 +871,16 @@ lacp_print_details(struct ds *ds, struct lacp *lacp) } static void -lacp_unixctl_show(struct unixctl_conn *conn, - const char *args, void *aux OVS_UNUSED) +lacp_unixctl_show(struct unixctl_conn *conn, int argc, const char *argv[], + void *aux OVS_UNUSED) { struct ds ds = DS_EMPTY_INITIALIZER; struct lacp *lacp; - if (strlen(args)) { - lacp = lacp_find(args); + if (argc > 1) { + lacp = lacp_find(argv[1]); if (!lacp) { - unixctl_command_reply(conn, 501, "no such lacp object"); + unixctl_command_reply_error(conn, "no such lacp object"); return; } lacp_print_details(&ds, lacp); @@ -888,6 +890,6 @@ lacp_unixctl_show(struct unixctl_conn *conn, } } - unixctl_command_reply(conn, 200, ds_cstr(&ds)); + unixctl_command_reply(conn, ds_cstr(&ds)); ds_destroy(&ds); }