X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Flacp.c;h=9daca3bd14010dff38de5c863a08a077fde8dbad;hb=f80022d9df98d29ee41176a4bc6cb91025da84b8;hp=89e70b75682e58f6e36c554f7a3b82c8ce22da35;hpb=bf83f7c82f28d920487fb00741e5b0b692d93d36;p=sliver-openvswitch.git diff --git a/lib/lacp.c b/lib/lacp.c index 89e70b756..9daca3bd1 100644 --- a/lib/lacp.c +++ b/lib/lacp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 Nicira Networks +/* Copyright (c) 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ #include #include "lacp.h" -#include #include #include "dynamic-string.h" @@ -101,7 +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. */ - bool heartbeat; /* LACP heartbeat mode. */ + + int ref_cnt; }; struct slave { @@ -199,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) { @@ -224,7 +241,7 @@ lacp_destroy(struct lacp *lacp) void lacp_configure(struct lacp *lacp, const struct lacp_settings *s) { - assert(!eth_addr_is_zero(s->id)); + ovs_assert(!eth_addr_is_zero(s->id)); if (!lacp->name || strcmp(s->name, lacp->name)) { free(lacp->name); @@ -232,11 +249,9 @@ lacp_configure(struct lacp *lacp, const struct lacp_settings *s) } if (!eth_addr_equals(lacp->sys_id, s->id) - || lacp->sys_priority != s->priority - || lacp->heartbeat != s->heartbeat) { + || lacp->sys_priority != s->priority) { memcpy(lacp->sys_id, s->id, ETH_ADDR_LEN); lacp->sys_priority = s->priority; - lacp->heartbeat = s->heartbeat; lacp->update = true; } @@ -365,6 +380,14 @@ lacp_slave_carrier_changed(const struct lacp *lacp, const void *slave_) } } +static bool +slave_may_enable__(struct slave *slave) +{ + /* The slave may be enabled if it's attached to an aggregator and its + * partner is synchronized.*/ + return slave->attached && (slave->partner.state & LACP_STATE_SYNC); +} + /* This function should be called before enabling 'slave_' to send or receive * traffic. If it returns false, 'slave_' should not enabled. As a * convenience, returns true if 'lacp' is NULL. */ @@ -372,24 +395,12 @@ bool lacp_slave_may_enable(const struct lacp *lacp, const void *slave_) { if (lacp) { - struct slave *slave = slave_lookup(lacp, slave_); - - /* The slave may be enabled if it's attached to an aggregator and its - * partner is synchronized.*/ - return slave->attached && (slave->partner.state & LACP_STATE_SYNC); + return slave_may_enable__(slave_lookup(lacp, slave_)); } else { return true; } } -/* Returns the port ID used for 'slave_' in LACP communications. */ -uint16_t -lacp_slave_get_port_id(const struct lacp *lacp, const void *slave_) -{ - struct slave *slave = slave_lookup(lacp, slave_); - return slave->port_id; -} - /* Returns true if partner information on 'slave_' is up to date. 'slave_' * not being current, generally indicates a connectivity problem, or a * misconfigured (or broken) partner. */ @@ -474,13 +485,6 @@ lacp_update_attached(struct lacp *lacp) struct lacp_info lead_pri; static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 10); - if (lacp->heartbeat) { - HMAP_FOR_EACH (slave, node, &lacp->slaves) { - slave->attached = slave->status != LACP_DEFAULTED; - } - return; - } - lacp->update = false; lead = NULL; @@ -593,7 +597,7 @@ slave_get_actor(struct slave *slave, struct lacp_info *actor) state |= LACP_STATE_EXP; } - if (lacp->heartbeat || hmap_count(&lacp->slaves) > 1) { + if (hmap_count(&lacp->slaves) > 1) { state |= LACP_STATE_AGG; } @@ -747,9 +751,6 @@ lacp_print_details(struct ds *ds, struct lacp *lacp) ds_put_format(ds, "---- %s ----\n", lacp->name); ds_put_format(ds, "\tstatus: %s", lacp->active ? "active" : "passive"); - if (lacp->heartbeat) { - ds_put_cstr(ds, " heartbeat"); - } if (lacp->negotiated) { ds_put_cstr(ds, " negotiated"); } @@ -759,7 +760,9 @@ lacp_print_details(struct ds *ds, struct lacp *lacp) ds_put_format(ds, "\tsys_priority: %u\n", lacp->sys_priority); ds_put_cstr(ds, "\taggregation key: "); if (lacp->key_slave) { - ds_put_format(ds, "%u", lacp->key_slave->port_id); + ds_put_format(ds, "%u", lacp->key_slave->key + ? lacp->key_slave->key + : lacp->key_slave->port_id); } else { ds_put_cstr(ds, "none"); } @@ -801,6 +804,8 @@ lacp_print_details(struct ds *ds, struct lacp *lacp) slave->attached ? "attached" : "detached"); ds_put_format(ds, "\tport_id: %u\n", slave->port_id); ds_put_format(ds, "\tport_priority: %u\n", slave->port_priority); + ds_put_format(ds, "\tmay_enable: %s\n", (slave_may_enable__(slave) + ? "true" : "false")); ds_put_format(ds, "\n\tactor sys_id: " ETH_ADDR_FMT "\n", ETH_ADDR_ARGS(actor.sys_id));