aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lacp.c17
-rw-r--r--lib/lacp.h1
-rw-r--r--vswitchd/bridge.c4
-rw-r--r--vswitchd/vswitch.xml4
4 files changed, 19 insertions, 7 deletions
diff --git a/lib/lacp.c b/lib/lacp.c
index a7f66a24..21d329eb 100644
--- a/lib/lacp.c
+++ b/lib/lacp.c
@@ -53,6 +53,7 @@ struct lacp {
bool strict; /* True if in strict mode. */
bool negotiated; /* True if LACP negotiations were successful. */
bool update; /* True if lacp_update() needs to be called. */
+ bool force_agg; /* Forces LACP_STATE_AGG bit on all slaves. */
};
struct slave {
@@ -190,6 +191,7 @@ lacp_configure(struct lacp *lacp, const struct lacp_settings *s)
lacp->active = s->active;
lacp->lacp_time = s->lacp_time;
+ lacp->force_agg = s->force_agg;
lacp->custom_time = MAX(TIME_UPDATE_INTERVAL, s->custom_time);
}
@@ -525,13 +527,14 @@ slave_set_expired(struct slave *slave)
static void
slave_get_actor(struct slave *slave, struct lacp_info *actor)
{
+ struct lacp *lacp = slave->lacp;
uint8_t state = 0;
- if (slave->lacp->active) {
+ if (lacp->active) {
state |= LACP_STATE_ACT;
}
- if (slave->lacp->lacp_time != LACP_TIME_SLOW) {
+ if (lacp->lacp_time != LACP_TIME_SLOW) {
state |= LACP_STATE_TIME;
}
@@ -547,20 +550,20 @@ slave_get_actor(struct slave *slave, struct lacp_info *actor)
state |= LACP_STATE_EXP;
}
- if (hmap_count(&slave->lacp->slaves) > 1) {
+ if (lacp->force_agg || hmap_count(&lacp->slaves) > 1) {
state |= LACP_STATE_AGG;
}
- if (slave->attached || !slave->lacp->negotiated) {
+ if (slave->attached || !lacp->negotiated) {
state |= LACP_STATE_COL | LACP_STATE_DIST;
}
actor->state = state;
- actor->key = htons(slave->lacp->key_slave->port_id);
+ actor->key = htons(lacp->key_slave->port_id);
actor->port_priority = htons(slave->port_priority);
actor->port_id = htons(slave->port_id);
- actor->sys_priority = htons(slave->lacp->sys_priority);
- memcpy(&actor->sys_id, slave->lacp->sys_id, ETH_ADDR_LEN);
+ actor->sys_priority = htons(lacp->sys_priority);
+ memcpy(&actor->sys_id, lacp->sys_id, ETH_ADDR_LEN);
}
/* Given 'slave', populates 'priority' with data representing its LACP link
diff --git a/lib/lacp.h b/lib/lacp.h
index 39656920..871056c4 100644
--- a/lib/lacp.h
+++ b/lib/lacp.h
@@ -89,6 +89,7 @@ struct lacp_settings {
enum lacp_time lacp_time;
long long int custom_time;
bool strict;
+ bool force_agg;
};
void lacp_init(void);
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index dee19a9b..270ab800 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -3193,6 +3193,10 @@ port_reconfigure_lacp(struct port *port)
"false"),
"true");
+ s.force_agg = !strcmp(get_port_other_config(port->cfg,
+ "lacp-force-aggregatable",
+ "false"), "true");
+
lacp_time = get_port_other_config(port->cfg, "lacp-time", "slow");
custom_time = atoi(lacp_time);
if (!strcmp(lacp_time, "fast")) {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 0ec1fd3c..e7548355 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -683,6 +683,10 @@
require successful LACP negotiations to enable any slaves.
Defaults to <code>false</code> which safely allows LACP to be used
with switches that do not support the protocol.</dd>
+ <dt><code>lacp-force-aggregatable</code></dt>
+ <dd> When <code>true</code>, forces all slaves managed by this
+ <ref table="Port"/> to advertise themselves as aggregatable even if
+ they normally wouldn't. Defaults to <code>false</code>.</dd>
</dl>
</column>
</group>