summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config/dhcp.h6
-rw-r--r--src/net/udp/dhcp.c8
2 files changed, 12 insertions, 2 deletions
diff --git a/src/config/dhcp.h b/src/config/dhcp.h
index 49fe16b9..bff5b56d 100644
--- a/src/config/dhcp.h
+++ b/src/config/dhcp.h
@@ -25,6 +25,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#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
* timeout for it. The PXE spec indicates waiting through the 4 & 8
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index 9c7b2fdc..9342ad21 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -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 );
}