diff mbox

[ovs-dev,v2] lacp: Select a may-enable IF as the lead IF

Message ID 20161221172627.31819-1-blp@ovn.org
State Accepted
Headers show

Commit Message

Ben Pfaff Dec. 21, 2016, 5:26 p.m. UTC
A reboot of one switch in an MC-LAG bond makes all bond links
to go down, causing a total connectivity loss for 3 seconds.

Packet capture shows that spurious LACP PDUs are sent to OVS with
a different MAC address (partner system id) during the final
stages of the MC-LAG switch reboot.

The current code selects a lead interface based on information
in the LACP PDU, regardless of its synchronization state. If a
non-synchronized interface is selected as the OVS lead interface
then all other interfaces are forced down as their stored partner
system id differs and the bond ends up with no working interface.
The bond recovers within three seconds after the last spurious
message.

To avoid the problem, this commit requires a lead interface
to be synchronized. In case no synchronized interface exists,
the selection of lead interface is done as in the current code.

Signed-off-by: Torgny Lindberg <torgny.lindberg@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
---
v1->v2: Rewrite preference for a synchronized interface in terms of a
comparison inside the loop.

 lib/lacp.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/lib/lacp.c b/lib/lacp.c
index ad6ef8e..84b2cf6 100644
--- a/lib/lacp.c
+++ b/lib/lacp.c
@@ -1,4 +1,4 @@ 
-/* Copyright (c) 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
+/* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -596,11 +596,13 @@  lacp_update_attached(struct lacp *lacp) OVS_REQUIRES(mutex)
 {
     struct slave *lead, *slave;
     struct lacp_info lead_pri;
+    bool lead_enable;
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 10);
 
     lacp->update = false;
 
     lead = NULL;
+    lead_enable = false;
     HMAP_FOR_EACH (slave, node, &lacp->slaves) {
         struct lacp_info pri;
 
@@ -623,9 +625,14 @@  lacp_update_attached(struct lacp *lacp) OVS_REQUIRES(mutex)
 
         slave->attached = true;
         slave_get_priority(slave, &pri);
+        bool enable = slave_may_enable__(slave);
 
-        if (!lead || memcmp(&pri, &lead_pri, sizeof pri) < 0) {
+        if (!lead
+            || enable > lead_enable
+            || (enable == lead_enable
+                && memcmp(&pri, &lead_pri, sizeof pri) < 0)) {
             lead = slave;
+            lead_enable = enable;
             lead_pri = pri;
         }
     }