[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-05-12 12:09:28 +01:00
parent ab9d7b0067
commit 2b4a3efcc6
+9 -4
View File
@@ -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 = &eth_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 |