]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[dhcp] Limit maximum number of DHCP discovery deferrals
authorMichael Brown <mcb30@ipxe.org>
Tue, 10 Nov 2015 14:05:46 +0000 (14:05 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 10 Nov 2015 14:05:46 +0000 (14:05 +0000)
For switches which remain permanently in the non-forwarding state (or
which erroneously report a non-forwarding state), ensure that iPXE
will eventually give up waiting for the link to become unblocked.

Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/config/dhcp.h
src/net/udp/dhcp.c

index 49fe16b924d316f01cd3c1bd662e0a96326e6995..bff5b56d63c1cd00930ff178d18eb49208d3283b 100644 (file)
@@ -24,6 +24,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#define DHCP_DISC_START_TIMEOUT_SEC  4       /* as per PXE spec */
 //#define DHCP_DISC_END_TIMEOUT_SEC    32      /* as per PXE spec */
 
+/*
+ * Maximum number of discovery deferrals due to blocked links
+ * (e.g. from non-forwarding STP ports)
+ */
+#define DHCP_DISC_MAX_DEFERRALS                60
+
 /*
  * ProxyDHCP offers are given precedence by continue to wait for them
  * after a valid DHCPOFFER is received.  We'll wait through this
index 9c7b2fdc252c691344fafd8ec635147c6b2114b1..9342ad21e492b20957250cd5e603471be23407f8 100644 (file)
@@ -444,7 +444,8 @@ static void dhcp_discovery_expired ( struct dhcp_session *dhcp ) {
        unsigned long elapsed = ( currticks() - dhcp->start );
 
        /* If link is blocked, defer DHCP discovery (and reset timeout) */
-       if ( netdev_link_blocked ( dhcp->netdev ) ) {
+       if ( netdev_link_blocked ( dhcp->netdev ) &&
+            ( dhcp->count <= DHCP_DISC_MAX_DEFERRALS ) ) {
                DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
                dhcp->start = currticks();
                start_timer_fixed ( &dhcp->timer,
@@ -1115,7 +1116,7 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
         * session state into packet traces.  Useful for extracting
         * debug information from non-debug builds.
         */
-       dhcppkt.dhcphdr->secs = htons ( ( ++(dhcp->count) << 2 ) |
+       dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
                                        ( dhcp->offer.s_addr ? 0x02 : 0 ) |
                                        ( dhcp->proxy_offer ? 0x01 : 0 ) );
 
@@ -1259,6 +1260,9 @@ static void dhcp_timer_expired ( struct retry_timer *timer, int fail ) {
                return;
        }
 
+       /* Increment transmission counter */
+       dhcp->count++;
+
        /* Handle timer expiry based on current state */
        dhcp->state->expired ( dhcp );
 }