Commit bdebeece5 (lacp: Require successful LACP negotiations when
configured.) makes successful LACP negotiation mandatory.
This change makes it configurable. The user has the option to
set other-config:lacp-fallback-slb to true if pre 1.5.0 behavior
is needed. The switch will fallback to balance-slb when LACP
negotiation fails or is unsupported by the partner switch. The
default is false, requiring a successful LACP negotiation (which is
the current behavior).

Signed-off-by: Dominic Curran <dominic.cur...@citrix.com>
---
 lib/bond.c           |   41 +++++++++++++++++++++++++++--------------
 lib/bond.h           |    1 +
 lib/lacp.c           |   15 +++++++++++++--
 lib/lacp.h           |    1 +
 vswitchd/bridge.c    |   17 +++++++++++++++++
 vswitchd/vswitch.xml |   19 +++++++++++++++++--
 6 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/lib/bond.c b/lib/bond.c
index 68ac068..6365cd0 100644
--- a/lib/bond.c
+++ b/lib/bond.c
@@ -103,6 +103,7 @@ struct bond {
 
     /* Legacy compatibility. */
     long long int next_fake_iface_update; /* LLONG_MAX if disabled. */
+    bool lacp_fallback_slb; /* fallback to balance-slb on lacp failure */
 
     /* Tag set saved for next bond_run().  This tag set is a kluge for cases
      * where we can't otherwise provide revalidation feedback to the client.
@@ -238,6 +239,11 @@ bond_reconfigure(struct bond *bond, const struct 
bond_settings *s)
     bond->updelay = s->up_delay;
     bond->downdelay = s->down_delay;
 
+    if (bond->lacp_fallback_slb != s->lacp_fallback_slb_cfg) {
+        bond->lacp_fallback_slb = s->lacp_fallback_slb_cfg;
+        revalidate = true;
+    }
+
     if (bond->rebalance_interval != s->rebalance_interval) {
         bond->rebalance_interval = s->rebalance_interval;
         revalidate = true;
@@ -463,8 +469,9 @@ bond_wait(struct bond *bond)
 static bool
 may_send_learning_packets(const struct bond *bond)
 {
-    return bond->lacp_status == LACP_DISABLED
-        && (bond->balance == BM_SLB || bond->balance == BM_AB)
+    return ((bond->lacp_status == LACP_DISABLED
+        && (bond->balance == BM_SLB || bond->balance == BM_AB))
+        || (bond->lacp_fallback_slb && bond->lacp_status == LACP_CONFIGURED))
         && bond->active_slave;
 }
 
@@ -546,10 +553,12 @@ bond_check_admissibility(struct bond *bond, const void 
*slave_,
      * packets to them.
      *
      * If LACP is configured, but LACP negotiations have been unsuccessful, we
-     * drop all incoming traffic. */
+     * drop all incoming traffic except if lacp_fallback_slb is true. */
     switch (bond->lacp_status) {
     case LACP_NEGOTIATED: return slave->enabled ? BV_ACCEPT : BV_DROP;
-    case LACP_CONFIGURED: return BV_DROP;
+    case LACP_CONFIGURED:
+        if (!bond->lacp_fallback_slb)
+            return BV_DROP;
     case LACP_DISABLED: break;
     }
 
@@ -578,9 +587,11 @@ bond_check_admissibility(struct bond *bond, const void 
*slave_,
 
     case BM_TCP:
         /* TCP balanced bonds require successful LACP negotiated. Based on the
-         * above check, LACP is off on this bond.  Therfore, we drop all
-         * incoming traffic. */
-        return BV_DROP;
+         * above check, LACP is off or lacp_fallback_slb is true on this bond.
+         * If lacp_fallback_slb is true fall through to BM_SLB case else, we
+         * drop all incoming traffic. */
+       if (!bond->lacp_fallback_slb)
+            return BV_DROP;
 
     case BM_SLB:
         /* Drop all packets for which we have learned a different input port,
@@ -1359,9 +1370,9 @@ choose_output_slave(const struct bond *bond, const struct 
flow *flow,
 {
     struct bond_entry *e;
 
-    if (bond->lacp_status == LACP_CONFIGURED) {
+    if (bond->lacp_status == LACP_CONFIGURED && !bond->lacp_fallback_slb) {
         /* LACP has been configured on this bond but negotiations were
-         * unsuccussful.  Drop all traffic. */
+         * unsuccussful and lacp_fallback_slb not true.  Drop all traffic. */
         return NULL;
     }
 
@@ -1370,13 +1381,15 @@ choose_output_slave(const struct bond *bond, const 
struct flow *flow,
         return bond->active_slave;
 
     case BM_TCP:
-        if (bond->lacp_status != LACP_NEGOTIATED) {
-            /* Must have LACP negotiations for TCP balanced bonds. */
+        if (bond->lacp_status == LACP_NEGOTIATED) {
+            if (wc)
+                flow_mask_hash_fields(wc, NX_HASH_FIELDS_SYMMETRIC_L4);
+        } else if (!((bond->lacp_status == LACP_CONFIGURED)
+            && bond->lacp_fallback_slb)) {
+            /* Must have LACP negotiations for TCP balanced bonds or LACP
+             * Configured with lacp_fallback_slb set to true. */
             return NULL;
         }
-        if (wc) {
-            flow_mask_hash_fields(wc, NX_HASH_FIELDS_SYMMETRIC_L4);
-        }
         /* Fall Through. */
     case BM_SLB:
         if (wc) {
diff --git a/lib/bond.h b/lib/bond.h
index 306cf42..f466383 100644
--- a/lib/bond.h
+++ b/lib/bond.h
@@ -54,6 +54,7 @@ struct bond_settings {
 
     /* Legacy compatibility. */
     bool fake_iface;            /* Update fake stats for netdev 'name'? */
+    bool lacp_fallback_slb_cfg;        /* fallback to balance-slb on lacp 
failure */
 };
 
 /* Program startup. */
diff --git a/lib/lacp.c b/lib/lacp.c
index 8bc115d..e2b6e91 100644
--- a/lib/lacp.c
+++ b/lib/lacp.c
@@ -100,6 +100,7 @@ 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 fallback_slb;       /* fallback to balance-slb on lacp failure */
 };
 
 struct slave {
@@ -238,6 +239,11 @@ lacp_configure(struct lacp *lacp, const struct 
lacp_settings *s)
 
     lacp->active = s->active;
     lacp->fast = s->fast;
+
+    if (lacp->fallback_slb != s->fallback_slb_cfg) {
+        lacp->fallback_slb = s->fallback_slb_cfg;
+        lacp->update = true;
+    }
 }
 
 /* Returns true if 'lacp' is configured in active mode, false if 'lacp' is
@@ -366,7 +372,9 @@ 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);
+    return slave->attached && (slave->partner.state & LACP_STATE_SYNC
+        || (slave->lacp && slave->lacp->fallback_slb
+        && slave->status == LACP_DEFAULTED));
 }
 
 /* This function should be called before enabling 'slave_' to send or receive
@@ -483,6 +491,8 @@ lacp_update_attached(struct lacp *lacp)
         }
 
         if (slave->status == LACP_DEFAULTED) {
+            if (lacp->fallback_slb)
+                slave->attached = true;
             continue;
         }
 
@@ -499,7 +509,8 @@ lacp_update_attached(struct lacp *lacp)
 
     if (lead) {
         HMAP_FOR_EACH (slave, node, &lacp->slaves) {
-            if (lead->partner.key != slave->partner.key
+            if ((lacp->fallback_slb && slave->status == LACP_DEFAULTED)
+                || lead->partner.key != slave->partner.key
                 || !eth_addr_equals(lead->partner.sys_id,
                                     slave->partner.sys_id)) {
                 slave->attached = false;
diff --git a/lib/lacp.h b/lib/lacp.h
index 399b39e..21f2290 100644
--- a/lib/lacp.h
+++ b/lib/lacp.h
@@ -35,6 +35,7 @@ struct lacp_settings {
     uint16_t priority;                /* System priority. */
     bool active;                      /* Active or passive mode? */
     bool fast;                        /* Fast or slow probe interval. */
+    bool fallback_slb_cfg;            /* fallback to BM_SLB on lacp failure */
 };
 
 void lacp_init(void);
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 4ac2b26..4c9e698 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -234,6 +234,7 @@ static struct lacp_settings *port_configure_lacp(struct 
port *,
                                                  struct lacp_settings *);
 static void port_configure_bond(struct port *, struct bond_settings *);
 static bool port_is_synthetic(const struct port *);
+static bool set_lacp_fallback_slb_cfg(struct port *);
 
 static void reconfigure_system_stats(const struct ovsrec_open_vswitch *);
 static void run_system_stats(void);
@@ -3264,6 +3265,17 @@ enable_lacp(struct port *port, bool *activep)
     }
 }
 
+static bool set_lacp_fallback_slb_cfg(struct port *port)
+{
+    const char *lacp_fallback_s;
+
+    lacp_fallback_s = smap_get(&port->cfg->other_config, "lacp-fallback-slb");
+    if (lacp_fallback_s && !strcmp(lacp_fallback_s, "true"))
+        return true;
+
+    return false;
+}
+
 static struct lacp_settings *
 port_configure_lacp(struct port *port, struct lacp_settings *s)
 {
@@ -3302,6 +3314,9 @@ port_configure_lacp(struct port *port, struct 
lacp_settings *s)
 
     lacp_time = smap_get(&port->cfg->other_config, "lacp-time");
     s->fast = lacp_time && !strcasecmp(lacp_time, "fast");
+
+    s->fallback_slb_cfg = set_lacp_fallback_slb_cfg(port);
+
     return s;
 }
 
@@ -3390,6 +3405,8 @@ port_configure_bond(struct port *port, struct 
bond_settings *s)
 
     s->fake_iface = port->cfg->bond_fake_iface;
 
+    s->lacp_fallback_slb_cfg = set_lacp_fallback_slb_cfg(port);
+
     LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
         netdev_set_miimon_interval(iface->netdev, miimon_interval);
     }
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 12780d6..2e894c5 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -925,7 +925,9 @@
 
       <p>
         The following modes require the upstream switch to support 802.3ad with
-        successful LACP negotiation:
+        successful LACP negotiation. If LACP negotiation fails and
+        other-config:lacp-fallback-slb is true, then <code>balance-slb</code>
+        style flow hashing is used:
       </p>
 
       <dl>
@@ -1015,7 +1017,8 @@
           in LACP negotiations initiated by a remote switch, but not allowed to
           initiate such negotiations themselves.  If LACP is enabled on a port
           whose partner switch does not support LACP, the bond will be
-          disabled.  Defaults to <code>off</code> if unset.
+          disabled, unless other-config:lacp-fallback-slb is set to true.
+          Defaults to <code>off</code> if unset.
         </column>
 
         <column name="other_config" key="lacp-system-id">
@@ -1043,6 +1046,18 @@
             rate of once every 30 seconds.
           </p>
         </column>
+
+        <column name="other_config" key="lacp-fallback-slb"
+          type='{"type": "boolean"}'>
+          <p>
+            Determines the behavior of openvswitch bond in LACP mode. If
+            the partner switch does not support LACP, setting this option
+            to <code>true</code> allows openvswitch to fallback to
+            balance-slb. If the option is set to <code>false</code>, the
+            bond will be disabled. In both the cases, once the partner switch
+            is configured to LACP mode then the bond will use LACP.
+          </p>
+        </column>
       </group>
 
       <group title="Rebalancing Configuration">
-- 
1.7.2.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to