From 2b4a3efcc6f904ed261e7728e3fe90cce090a496 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 12 May 2026 12:09:28 +0100 Subject: [PATCH] [lacp] Use the same system identifier for all ports Commit 3d43789 ("[lacp] Detect and ignore erroneously looped back LACP packets") added protection against LACP packet storms that arise when our own transmitted packets are somehow looped back to the same port, but does not protect against a situation in which we have two different ports that are externally bridged to each other. This situation is unlikely to arise in practice since a properly configured link partner should not be both sending and forwarding LACP packets. Triggering this situation essentially requires our two ports to be connected to a non-LACP-capable switch, while another port on the same switch is connected to a separate device that is sending out LACP packets. Guard against this situation by using the MAC address of the first network device as the LACP system identifier, thereby allowing the loopback detection to reject any packets that were sent from any of our ports. Since the system identifier is no longer unique between ports, use the guaranteed-unique network device scope ID as the group key to indicate that we do not support aggregation. Signed-off-by: Michael Brown --- src/net/eth_slow.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/net/eth_slow.c b/src/net/eth_slow.c index fb4e0d972..e3b6a75a7 100644 --- a/src/net/eth_slow.c +++ b/src/net/eth_slow.c @@ -150,12 +150,17 @@ static int eth_slow_lacp_rx ( struct io_buffer *iobuf, struct net_device *netdev ) { union eth_slow_packet *eth_slow = iobuf->data; struct eth_slow_lacp *lacp = ð_slow->lacp; + struct net_device *system; unsigned int interval; eth_slow_lacp_dump ( iobuf, netdev, "RX" ); + /* Obtain system identifier */ + system = list_first_entry ( &net_devices, struct net_device, list ); + assert ( system != NULL ); + /* Check for looped-back packets */ - if ( memcmp ( lacp->actor.system, netdev->ll_addr, + if ( memcmp ( lacp->actor.system, system->ll_addr, sizeof ( lacp->actor.system ) ) == 0 ) { DBGC ( netdev, "SLOW %s RX loopback detected\n", netdev->name ); @@ -197,11 +202,11 @@ static int eth_slow_lacp_rx ( struct io_buffer *iobuf, lacp->actor.tlv.type = ETH_SLOW_TLV_LACP_ACTOR; lacp->actor.tlv.length = ETH_SLOW_TLV_LACP_ACTOR_LEN; lacp->actor.system_priority = htons ( LACP_SYSTEM_PRIORITY_MAX ); - memcpy ( lacp->actor.system, netdev->ll_addr, + memcpy ( lacp->actor.system, system->ll_addr, sizeof ( lacp->actor.system ) ); - lacp->actor.key = htons ( 1 ); + lacp->actor.key = htons ( netdev->scope_id ); lacp->actor.port_priority = htons ( LACP_PORT_PRIORITY_MAX ); - lacp->actor.port = htons ( 1 ); + lacp->actor.port = htons ( netdev->scope_id ); lacp->actor.state = ( LACP_STATE_AGGREGATABLE | LACP_STATE_IN_SYNC | LACP_STATE_COLLECTING |