mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 20:40:25 +03:00
[dhcp] Handle DHCPNAK by returning to discovery state
Handle a DHCPNAK by returning to the discovery state to allow iPXE to attempt to obtain a replacement IPv4 address. Reuse the existing logic for deferring discovery when the link is blocked: this avoids hammering a misconfigured DHCP server with a non-stop stream of requests and allows the DHCP process to eventually time out and fail. Originally-implemented-by: Blake Rouse <blake.rouse@canonical.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -443,6 +443,26 @@ static void dhcp_discovery_rx ( struct dhcp_session *dhcp,
|
||||
dhcp_set_state ( dhcp, &dhcp_state_request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer DHCP discovery
|
||||
*
|
||||
* @v dhcp DHCP session
|
||||
*/
|
||||
static void dhcp_defer ( struct dhcp_session *dhcp ) {
|
||||
|
||||
/* Do nothing if we have reached the deferral limit */
|
||||
if ( dhcp->count > DHCP_DISC_MAX_DEFERRALS )
|
||||
return;
|
||||
|
||||
/* Return to discovery state */
|
||||
DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
|
||||
dhcp_set_state ( dhcp, &dhcp_state_discover );
|
||||
|
||||
/* Delay first DHCPDISCOVER */
|
||||
start_timer_fixed ( &dhcp->timer,
|
||||
( DHCP_DISC_START_TIMEOUT_SEC * TICKS_PER_SEC ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle timer expiry during DHCP discovery
|
||||
*
|
||||
@@ -462,14 +482,8 @@ static void dhcp_discovery_expired ( struct dhcp_session *dhcp ) {
|
||||
dhcp_tx ( dhcp );
|
||||
|
||||
/* If link is blocked, defer DHCP discovery timeout */
|
||||
if ( netdev_link_blocked ( dhcp->netdev ) &&
|
||||
( dhcp->count <= DHCP_DISC_MAX_DEFERRALS ) ) {
|
||||
DBGC ( dhcp, "DHCP %p deferring discovery timeout\n", dhcp );
|
||||
dhcp->start = currticks();
|
||||
start_timer_fixed ( &dhcp->timer,
|
||||
( DHCP_DISC_START_TIMEOUT_SEC *
|
||||
TICKS_PER_SEC ) );
|
||||
}
|
||||
if ( netdev_link_blocked ( dhcp->netdev ) )
|
||||
dhcp_defer ( dhcp );
|
||||
}
|
||||
|
||||
/** DHCP discovery state operations */
|
||||
@@ -553,9 +567,17 @@ static void dhcp_request_rx ( struct dhcp_session *dhcp,
|
||||
DBGC ( dhcp, " for %s", inet_ntoa ( ip ) );
|
||||
DBGC ( dhcp, "\n" );
|
||||
|
||||
/* Filter out unacceptable responses */
|
||||
/* Filter out invalid port */
|
||||
if ( peer->sin_port != htons ( BOOTPS_PORT ) )
|
||||
return;
|
||||
|
||||
/* Handle DHCPNAK */
|
||||
if ( msgtype == DHCPNAK ) {
|
||||
dhcp_defer ( dhcp );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Filter out unacceptable responses */
|
||||
if ( msgtype /* BOOTP */ && ( msgtype != DHCPACK ) )
|
||||
return;
|
||||
if ( server_id.s_addr != dhcp->server.s_addr )
|
||||
|
||||
Reference in New Issue
Block a user