mirror of https://github.com/ipxe/ipxe.git
[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>pull/310/head
parent
7c8fc2cae8
commit
1192edf394
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue