lacp: Prohibiting bonding with remote having different key than 1st member 92/32292/4
authorSteven Luong <sluong@cisco.com>
Wed, 12 May 2021 21:38:22 +0000 (14:38 -0700)
committerDamjan Marion <dmarion@me.com>
Thu, 13 May 2021 20:53:56 +0000 (20:53 +0000)
After forming the bonding with 1st remote member, Subsequent member must
have the same key in order to join the same bonding group.

Type: fix

Signed-off-by: Steven Luong <sluong@cisco.com>
Change-Id: I9ff6d6c083a5b6a26beedbd7181d5a120cb5710b

src/plugins/lacp/input.c
src/plugins/lacp/node.h
src/plugins/lacp/rx_machine.c
src/plugins/lacp/selection.c

index 4a69e0f..ebca2ad 100644 (file)
@@ -36,10 +36,8 @@ lacp_packet_scan (vlib_main_t * vm, member_if_t * mif)
       (lacpdu->terminator.tlv_length != 0))
     return (LACP_ERROR_BAD_TLV);
 
-  lacp_machine_dispatch (&lacp_rx_machine, vm, mif,
-                        LACP_RX_EVENT_PDU_RECEIVED, &mif->rx_state);
-
-  return LACP_ERROR_NONE;
+  return lacp_machine_dispatch (&lacp_rx_machine, vm, mif,
+                               LACP_RX_EVENT_PDU_RECEIVED, &mif->rx_state);
 }
 
 static void
index 0c4e457..165131a 100644 (file)
@@ -58,13 +58,15 @@ typedef enum
   }
 
 /* Packet counters */
-#define foreach_lacp_error                                               \
-_ (NONE, "good lacp packets -- consumed")                               \
-_ (CACHE_HIT, "good lacp packets -- cache hit")                          \
-_ (UNSUPPORTED, "unsupported slow protocol packets")                     \
-_ (TOO_SMALL, "bad lacp packets -- packet too small")                    \
-_ (BAD_TLV, "bad lacp packets -- bad TLV length")                        \
-_ (DISABLED, "lacp packets received on disabled interfaces")
+#define foreach_lacp_error                                                    \
+  _ (NONE, "good lacp packets -- consumed")                                   \
+  _ (CACHE_HIT, "good lacp packets -- cache hit")                             \
+  _ (UNSUPPORTED, "unsupported slow protocol packets")                        \
+  _ (TOO_SMALL, "bad lacp packets -- packet too small")                       \
+  _ (BAD_TLV, "bad lacp packets -- bad TLV length")                           \
+  _ (BAD_KEY, "Bad key")                                                      \
+  _ (LOOPBACK_PORT, "loopback port")                                          \
+  _ (DISABLED, "lacp packets received on disabled interfaces")
 
 typedef enum
 {
@@ -153,7 +155,7 @@ void lacp_init_rx_machine (vlib_main_t * vm, member_if_t * mif);
 void lacp_init_tx_machine (vlib_main_t * vm, member_if_t * mif);
 void lacp_init_ptx_machine (vlib_main_t * vm, member_if_t * mif);
 void lacp_init_mux_machine (vlib_main_t * vm, member_if_t * mif);
-void lacp_selection_logic (vlib_main_t * vm, member_if_t * mif);
+int lacp_selection_logic (vlib_main_t *vm, member_if_t *mif);
 void lacp_send_lacp_pdu (vlib_main_t * vm, member_if_t * mif);
 
 static inline void
index 6e36a66..2fadbe6 100644 (file)
@@ -371,9 +371,8 @@ lacp_rx_action_current (void *p1, void *p2)
   mif->actor.state &= ~LACP_STATE_EXPIRED;
   if (lacp_port_is_moved (vm, mif))
     lacp_set_port_moved (vm, mif, 1);
-  lacp_selection_logic (vm, mif);
 
-  return 0;
+  return lacp_selection_logic (vm, mif);
 }
 
 static u8 *
index f3fb6b9..0c9f036 100644 (file)
 #include <vnet/bonding/node.h>
 #include <lacp/node.h>
 
-static void
-lacp_set_port_selected (vlib_main_t * vm, member_if_t * mif)
+static int
+lacp_set_port_selected (vlib_main_t *vm, bond_if_t *bif, member_if_t *mif)
 {
+  uword p;
+  member_if_t *mif2;
+
   /* Handle loopback port */
   if (!memcmp (mif->partner.system, mif->actor.system, 6) &&
       (mif->partner.key == mif->actor.key))
     {
       mif->loopback_port = 1;
       mif->actor.state &= ~LACP_STATE_AGGREGATION;
+      mif->selected = LACP_PORT_UNSELECTED;
+      lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
+                            LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
+      return LACP_ERROR_LOOPBACK_PORT;
+    }
+  if (vec_len (bif->active_members))
+    {
+      p = *vec_elt_at_index (bif->active_members, 0);
+      mif2 = bond_get_member_by_sw_if_index (p);
+      if ((mif2->partner.key != mif->partner.key) ||
+         memcmp (mif2->partner.system, mif->partner.system, 6))
+       {
+         mif->selected = LACP_PORT_UNSELECTED;
+         lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
+                                LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
+         return LACP_ERROR_BAD_KEY;
+       }
     }
   mif->selected = LACP_PORT_SELECTED;
 
@@ -37,23 +57,23 @@ lacp_set_port_selected (vlib_main_t * vm, member_if_t * mif)
       break;
     case LACP_MUX_STATE_WAITING:
       if (!mif->ready)
-       return;
+       return LACP_ERROR_NONE;
       break;
     case LACP_MUX_STATE_ATTACHED:
       if (!(mif->partner.state & LACP_STATE_SYNCHRONIZATION))
-       return;
+       return LACP_ERROR_NONE;
       break;
     case LACP_MUX_STATE_COLLECTING_DISTRIBUTING:
       break;
     default:
       break;
     }
-  lacp_machine_dispatch (&lacp_mux_machine, vm, mif, LACP_MUX_EVENT_SELECTED,
-                        &mif->mux_state);
+  return lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
+                               LACP_MUX_EVENT_SELECTED, &mif->mux_state);
 }
 
-void
-lacp_selection_logic (vlib_main_t * vm, member_if_t * mif)
+int
+lacp_selection_logic (vlib_main_t *vm, member_if_t *mif)
 {
   member_if_t *mif2;
   bond_if_t *bif;
@@ -80,7 +100,7 @@ lacp_selection_logic (vlib_main_t * vm, member_if_t * mif)
       }
   }
 out:
-  lacp_set_port_selected (vm, mif);
+  return lacp_set_port_selected (vm, bif, mif);
 }
 
 /*