#include "ofpbuf.h"
#include "packets.h"
#include "poll-loop.h"
+#include "timer.h"
#include "timeval.h"
#include "unixctl.h"
#include "vlog.h"
struct hmap slaves; /* Slaves this LACP object controls. */
struct slave *key_slave; /* Slave whose ID will be the aggregation key. */
+ bool fast; /* Fast or Slow LACP time. */
bool negotiated; /* True if LACP negotiations were successful. */
bool update; /* True if lacp_update() needs to be called. */
};
bool enabled; /* Enabled. Traffic is flowing. */
struct lacp_info partner; /* Partner information. */
struct lacp_info ntt_actor; /* Used to decide if we Need To Transmit. */
- long long int tx; /* Next message transmission time. */
- long long int rx; /* Expected message receive time. */
+ struct timer tx; /* Next message transmission timer. */
+ struct timer rx; /* Expected message receive timer. */
};
static struct list all_lacps = LIST_INITIALIZER(&all_lacps);
}
}
-/* Configures 'lacp' with the given 'name', 'sys_id', 'sys_priority', and
- * 'active' parameters. */
+/* Configures 'lacp' with settings from 's'. */
void
-lacp_configure(struct lacp *lacp, const char *name,
- uint8_t sys_id[ETH_ADDR_LEN], uint16_t sys_priority,
- bool active)
+lacp_configure(struct lacp *lacp, const struct lacp_settings *s)
{
- if (!lacp->name || strcmp(name, lacp->name)) {
+ if (!lacp->name || strcmp(s->name, lacp->name)) {
free(lacp->name);
- lacp->name = xstrdup(name);
+ lacp->name = xstrdup(s->name);
}
- memcpy(lacp->sys_id, sys_id, ETH_ADDR_LEN);
- lacp->sys_priority = sys_priority;
- lacp->active = active;
+ memcpy(lacp->sys_id, s->id, ETH_ADDR_LEN);
+ lacp->sys_priority = s->priority;
+ lacp->active = s->active;
+ lacp->fast = s->fast;
+}
+
+/* Returns true if 'lacp' is configured in active mode, false if 'lacp' is
+ * configured for passive mode. */
+bool
+lacp_is_active(const struct lacp *lacp)
+{
+ return lacp->active;
}
/* Processes 'pdu', a parsed LACP packet received on 'slave_'. This function
struct slave *slave = slave_lookup(lacp, slave_);
slave->status = LACP_CURRENT;
- slave->rx = time_msec() + LACP_SLOW_TIME_RX;
+ timer_set_duration(&slave->rx, (lacp->fast
+ ? LACP_FAST_TIME_RX
+ : LACP_SLOW_TIME_RX));
slave->ntt_actor = pdu->partner;
/* Registers 'slave_' as subordinate to 'lacp'. This should be called at least
* once per slave in a LACP managed bond. Should also be called whenever a
- * slave's name, port_id, or port_priority change. */
+ * slave's settings change. */
void
-lacp_slave_register(struct lacp *lacp, void *slave_, const char *name,
- uint16_t port_id, uint16_t port_priority)
+lacp_slave_register(struct lacp *lacp, void *slave_,
+ const struct lacp_slave_settings *s)
{
struct slave *slave = slave_lookup(lacp, slave_);
}
}
- if (!slave->name || strcmp(name, slave->name)) {
+ if (!slave->name || strcmp(s->name, slave->name)) {
free(slave->name);
- slave->name = xstrdup(name);
+ slave->name = xstrdup(s->name);
}
- if (slave->port_id != port_id || slave->port_priority != port_priority) {
-
- slave->port_id = port_id;
- slave->port_priority = port_priority;
+ if (slave->port_id != s->id || slave->port_priority != s->priority) {
+ slave->port_id = s->id;
+ slave->port_priority = s->priority;
lacp->update = true;
struct slave *slave;
HMAP_FOR_EACH (slave, node, &lacp->slaves) {
- if (time_msec() >= slave->rx) {
+ if (timer_expired(&slave->rx)) {
if (slave->status == LACP_CURRENT) {
slave_set_expired(slave);
} else if (slave->status == LACP_EXPIRED) {
slave_get_actor(slave, &actor);
- if (time_msec() >= slave->tx
+ if (timer_expired(&slave->tx)
|| !info_tx_equal(&actor, &slave->ntt_actor)) {
slave->ntt_actor = actor;
compose_lacp_pdu(&actor, &slave->partner, &pdu);
send_pdu(slave->aux, &pdu);
- slave->tx = time_msec() +
- (slave->partner.state & LACP_STATE_TIME
- ? LACP_FAST_TIME_TX
- : LACP_SLOW_TIME_TX);
+ timer_set_duration(&slave->tx,
+ (slave->partner.state & LACP_STATE_TIME
+ ? LACP_FAST_TIME_TX
+ : LACP_SLOW_TIME_TX));
}
}
}
HMAP_FOR_EACH (slave, node, &lacp->slaves) {
if (slave_may_tx(slave)) {
- poll_timer_wait_until(slave->tx);
+ timer_wait(&slave->tx);
}
if (slave->status != LACP_DEFAULTED) {
- poll_timer_wait_until(slave->rx);
+ timer_wait(&slave->rx);
}
}
}
slave->status = LACP_EXPIRED;
slave->partner.state |= LACP_STATE_TIME;
slave->partner.state &= ~LACP_STATE_SYNC;
-
- slave->rx = time_msec() + LACP_FAST_TIME_RX;
+ timer_set_duration(&slave->rx, LACP_FAST_TIME_RX);
}
static void
state |= LACP_STATE_ACT;
}
+ if (slave->lacp->fast) {
+ state |= LACP_STATE_TIME;
+ }
+
if (slave->attached) {
state |= LACP_STATE_SYNC;
}