Browse Source

[lacp] Mark link as blocked if partner is not yet up and running

Mark the link as blocked if the LACP partner is not reporting itself
as being in sync, collecting, and distributing.

This matches the behaviour for STP: we mark the link as blocked if we
detect that the switch is actively blocking traffic, in order to
extend the DHCP discovery period and so prevent boot failures on
switches that take an excessively long time to enable ports.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
33d79d5d2b
2 changed files with 28 additions and 0 deletions
  1. 6
    0
      src/include/ipxe/eth_slow.h
  2. 22
    0
      src/net/eth_slow.c

+ 6
- 0
src/include/ipxe/eth_slow.h View File

190
  */
190
  */
191
 #define LACP_STATE_EXPIRED 0x80
191
 #define LACP_STATE_EXPIRED 0x80
192
 
192
 
193
+/** LACP fast interval (1 second) */
194
+#define LACP_INTERVAL_FAST 1
195
+
196
+/** LACP slow interval (30 seconds) */
197
+#define LACP_INTERVAL_SLOW 30
198
+
193
 /** LACP collector TLV */
199
 /** LACP collector TLV */
194
 struct eth_slow_lacp_collector_tlv {
200
 struct eth_slow_lacp_collector_tlv {
195
 	/** TLV header */
201
 	/** TLV header */

+ 22
- 0
src/net/eth_slow.c View File

27
 #include <string.h>
27
 #include <string.h>
28
 #include <byteswap.h>
28
 #include <byteswap.h>
29
 #include <errno.h>
29
 #include <errno.h>
30
+#include <ipxe/timer.h>
30
 #include <ipxe/iobuf.h>
31
 #include <ipxe/iobuf.h>
31
 #include <ipxe/netdevice.h>
32
 #include <ipxe/netdevice.h>
32
 #include <ipxe/if_ether.h>
33
 #include <ipxe/if_ether.h>
148
 			      struct net_device *netdev ) {
149
 			      struct net_device *netdev ) {
149
 	union eth_slow_packet *eth_slow = iobuf->data;
150
 	union eth_slow_packet *eth_slow = iobuf->data;
150
 	struct eth_slow_lacp *lacp = &eth_slow->lacp;
151
 	struct eth_slow_lacp *lacp = &eth_slow->lacp;
152
+	unsigned int interval;
151
 
153
 
152
 	eth_slow_lacp_dump ( iobuf, netdev, "RX" );
154
 	eth_slow_lacp_dump ( iobuf, netdev, "RX" );
153
 
155
 
156
+	/* If partner is not in sync, collecting, and distributing,
157
+	 * then block the link until after the next expected LACP
158
+	 * packet.
159
+	 */
160
+	if ( ~lacp->partner.state & ( LACP_STATE_IN_SYNC |
161
+				      LACP_STATE_COLLECTING |
162
+				      LACP_STATE_DISTRIBUTING ) ) {
163
+		DBGC ( netdev, "SLOW %s LACP partner is down\n", netdev->name );
164
+		interval = ( ( lacp->partner.state & LACP_STATE_FAST ) ?
165
+			     ( ( LACP_INTERVAL_FAST + 1 ) * TICKS_PER_SEC ) :
166
+			     ( ( LACP_INTERVAL_SLOW + 1 ) * TICKS_PER_SEC ) );
167
+		netdev_link_block ( netdev, interval );
168
+	} else {
169
+		if ( netdev_link_blocked ( netdev ) ) {
170
+			DBGC ( netdev, "SLOW %s LACP partner is up\n",
171
+			       netdev->name );
172
+		}
173
+		netdev_link_unblock ( netdev );
174
+	}
175
+
154
 	/* Build response */
176
 	/* Build response */
155
 	memset ( lacp->reserved, 0, sizeof ( lacp->reserved ) );
177
 	memset ( lacp->reserved, 0, sizeof ( lacp->reserved ) );
156
 	memset ( &lacp->terminator, 0, sizeof ( lacp->terminator ) );
178
 	memset ( &lacp->terminator, 0, sizeof ( lacp->terminator ) );

Loading…
Cancel
Save