summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2021-05-12 14:38:22 -0700
committerDamjan Marion <dmarion@me.com>2021-05-13 20:53:56 +0000
commit9f07085ab37d9bc27d2f2ccc4d651d7295f9b33c (patch)
tree5bda76943958644a596f46dbd38ec02f068572a0
parente4c8d69013367a545c54df44dcda6b192d408b95 (diff)
lacp: Prohibiting bonding with remote having different key than 1st member
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
-rw-r--r--src/plugins/lacp/input.c6
-rw-r--r--src/plugins/lacp/node.h18
-rw-r--r--src/plugins/lacp/rx_machine.c3
-rw-r--r--src/plugins/lacp/selection.c38
4 files changed, 42 insertions, 23 deletions
diff --git a/src/plugins/lacp/input.c b/src/plugins/lacp/input.c
index 4a69e0fb02a..ebca2ad9185 100644
--- a/src/plugins/lacp/input.c
+++ b/src/plugins/lacp/input.c
@@ -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
diff --git a/src/plugins/lacp/node.h b/src/plugins/lacp/node.h
index 0c4e4572c07..165131afae5 100644
--- a/src/plugins/lacp/node.h
+++ b/src/plugins/lacp/node.h
@@ -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
diff --git a/src/plugins/lacp/rx_machine.c b/src/plugins/lacp/rx_machine.c
index 6e36a661034..2fadbe636cf 100644
--- a/src/plugins/lacp/rx_machine.c
+++ b/src/plugins/lacp/rx_machine.c
@@ -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 *
diff --git a/src/plugins/lacp/selection.c b/src/plugins/lacp/selection.c
index f3fb6b9faa4..0c9f036308d 100644
--- a/src/plugins/lacp/selection.c
+++ b/src/plugins/lacp/selection.c
@@ -19,15 +19,35 @@
#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);
}
/*