[dhcp] Clarify language surrounding ProxyDHCP

Remove the lazy assumption that ProxyDHCP == "DHCP with option 60 set
to PXEClient", and explicitly separate the notion of ProxyDHCP from
the notion of packets containing PXE options.
pull/1/head
Michael Brown 2009-01-23 01:47:33 +00:00
parent 773d9631ef
commit 3f814f08e5
2 changed files with 56 additions and 55 deletions

View File

@ -25,8 +25,8 @@ struct dhcp_pxe_boot_menu_item;
/** BOOTP/DHCP client port */ /** BOOTP/DHCP client port */
#define BOOTPC_PORT 68 #define BOOTPC_PORT 68
/** ProxyDHCP server port */ /** PXE server port */
#define PROXYDHCP_PORT 4011 #define PXE_PORT 4011
/** Construct a tag value for an encapsulated option /** Construct a tag value for an encapsulated option
* *
@ -207,12 +207,12 @@ struct dhcp_pxe_boot_menu_item;
* *
*/ */
/** Ignore ProxyDHCP /** Skip PXE DHCP protocol extensions such as ProxyDHCP
* *
* If set to a non-zero value, gPXE will not wait for ProxyDHCP offers * If set to a non-zero value, gPXE will not wait for ProxyDHCP offers
* and will ignore any ProxyDHCP offers that it receives. * and will ignore any PXE-specific DHCP offers that it receives.
*/ */
#define DHCP_EB_NO_PROXYDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 ) #define DHCP_EB_NO_PXEDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 )
/** Network device descriptor /** Network device descriptor
* *

View File

@ -340,14 +340,16 @@ struct dhcp_session {
* (e.g. @c DHCPDISCOVER). * (e.g. @c DHCPDISCOVER).
*/ */
enum dhcp_session_state state; enum dhcp_session_state state;
/** DHCPOFFER obtained during DHCPDISCOVER */ /** DHCPOFFER obtained during DHCPDISCOVER containing IP address */
struct dhcp_settings *dhcpoffer; struct dhcp_settings *dhcpoffer;
/** ProxyDHCPOFFER obtained during DHCPDISCOVER */ /** DHCPOFFER obtained during DHCPDISCOVER containing "PXEClient" */
struct dhcp_settings *proxydhcpoffer; struct dhcp_settings *pxedhcpoffer;
/** DHCPACK obtained during DHCPREQUEST */ /** DHCPACK obtained during DHCPREQUEST containing IP address */
struct dhcp_settings *dhcpack; struct dhcp_settings *dhcpack;
/** ProxyDHCPACK obtained during ProxyDHCPREQUEST */ /** DHCPACK obtained during DHCPREQUEST or ProxyDHCPREQUEST
struct dhcp_settings *proxydhcpack; * containing "PXEClient"
*/
struct dhcp_settings *pxedhcpack;
/** BootServerDHCPACK obtained during BootServerDHCPREQUEST */ /** BootServerDHCPACK obtained during BootServerDHCPREQUEST */
struct dhcp_settings *bsdhcpack; struct dhcp_settings *bsdhcpack;
/** Retransmission timer */ /** Retransmission timer */
@ -367,9 +369,9 @@ static void dhcp_free ( struct refcnt *refcnt ) {
netdev_put ( dhcp->netdev ); netdev_put ( dhcp->netdev );
dhcpset_put ( dhcp->dhcpoffer ); dhcpset_put ( dhcp->dhcpoffer );
dhcpset_put ( dhcp->proxydhcpoffer ); dhcpset_put ( dhcp->pxedhcpoffer );
dhcpset_put ( dhcp->dhcpack ); dhcpset_put ( dhcp->dhcpack );
dhcpset_put ( dhcp->proxydhcpack ); dhcpset_put ( dhcp->pxedhcpack );
dhcpset_put ( dhcp->bsdhcpack ); dhcpset_put ( dhcp->bsdhcpack );
free ( dhcp ); free ( dhcp );
} }
@ -586,7 +588,7 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
static int dhcp_tx ( struct dhcp_session *dhcp ) { static int dhcp_tx ( struct dhcp_session *dhcp ) {
static struct sockaddr_in dest = { static struct sockaddr_in dest = {
.sin_family = AF_INET, .sin_family = AF_INET,
.sin_port = htons ( PROXYDHCP_PORT ), .sin_port = htons ( PXE_PORT ),
}; };
static struct sockaddr_in src = { static struct sockaddr_in src = {
.sin_family = AF_INET, .sin_family = AF_INET,
@ -624,11 +626,11 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
break; break;
case DHCP_STATE_PROXYREQUEST: case DHCP_STATE_PROXYREQUEST:
assert ( dhcp->dhcpoffer ); assert ( dhcp->dhcpoffer );
assert ( dhcp->proxydhcpoffer ); assert ( dhcp->pxedhcpoffer );
assert ( dhcp->dhcpack ); assert ( dhcp->dhcpack );
msgtype = DHCPREQUEST; msgtype = DHCPREQUEST;
ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr; ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr;
dhcppkt_fetch ( &dhcp->proxydhcpoffer->dhcppkt, dhcppkt_fetch ( &dhcp->pxedhcpoffer->dhcppkt,
DHCP_SERVER_IDENTIFIER, &dest.sin_addr, DHCP_SERVER_IDENTIFIER, &dest.sin_addr,
sizeof ( dest.sin_addr ) ); sizeof ( dest.sin_addr ) );
meta.dest = ( struct sockaddr * ) &dest; meta.dest = ( struct sockaddr * ) &dest;
@ -638,16 +640,16 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
break; break;
case DHCP_STATE_BSREQUEST: case DHCP_STATE_BSREQUEST:
assert ( dhcp->dhcpoffer ); assert ( dhcp->dhcpoffer );
assert ( dhcp->proxydhcpoffer ); assert ( dhcp->pxedhcpoffer );
assert ( dhcp->dhcpack ); assert ( dhcp->dhcpack );
assert ( dhcp->proxydhcpack ); assert ( dhcp->pxedhcpack );
msgtype = DHCPREQUEST; msgtype = DHCPREQUEST;
ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr; ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr;
dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt, dhcppkt_fetch ( &dhcp->pxedhcpack->dhcppkt,
DHCP_PXE_BOOT_SERVER_MCAST, DHCP_PXE_BOOT_SERVER_MCAST,
&dest.sin_addr, sizeof ( dest.sin_addr ) ); &dest.sin_addr, sizeof ( dest.sin_addr ) );
meta.dest = ( struct sockaddr * ) &dest; meta.dest = ( struct sockaddr * ) &dest;
dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt, dhcppkt_fetch ( &dhcp->pxedhcpack->dhcppkt,
DHCP_PXE_BOOT_MENU, &menu_item.type, DHCP_PXE_BOOT_MENU, &menu_item.type,
sizeof ( menu_item.type ) ); sizeof ( menu_item.type ) );
assert ( dest.sin_addr.s_addr ); assert ( dest.sin_addr.s_addr );
@ -744,21 +746,21 @@ static void dhcp_next_state ( struct dhcp_session *dhcp ) {
dhcp_set_state ( dhcp, DHCP_STATE_REQUEST ); dhcp_set_state ( dhcp, DHCP_STATE_REQUEST );
break; break;
case DHCP_STATE_REQUEST: case DHCP_STATE_REQUEST:
if ( dhcp->proxydhcpoffer ) { if ( dhcp->pxedhcpoffer ) {
/* Store DHCPACK as ProxyDHCPACK. This /* Store DHCPACK as PXEDHCPACK. This handles
* handles the case in which the DHCP server * the case in which the DHCP server itself
* itself responds with "PXEClient" and PXE * responds with "PXEClient" and PXE options
* options but there is no actual ProxyDHCP * but there is no ProxyDHCP server resident
* server resident on the machine. * on the machine.
*/ */
dhcp->proxydhcpack = dhcpset_get ( dhcp->dhcpack ); dhcp->pxedhcpack = dhcpset_get ( dhcp->dhcpack );
dhcp_set_state ( dhcp, DHCP_STATE_PROXYREQUEST ); dhcp_set_state ( dhcp, DHCP_STATE_PROXYREQUEST );
break; break;
} }
/* Fall through */ /* Fall through */
case DHCP_STATE_PROXYREQUEST: case DHCP_STATE_PROXYREQUEST:
if ( dhcp->proxydhcpack ) { if ( dhcp->pxedhcpack ) {
dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt, dhcppkt_fetch ( &dhcp->pxedhcpack->dhcppkt,
DHCP_PXE_BOOT_SERVER_MCAST, DHCP_PXE_BOOT_SERVER_MCAST,
&bs_mcast, sizeof ( bs_mcast ) ); &bs_mcast, sizeof ( bs_mcast ) );
if ( bs_mcast.s_addr ) { if ( bs_mcast.s_addr ) {
@ -827,7 +829,7 @@ static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
struct in_addr server_id = { 0 }; struct in_addr server_id = { 0 };
char vci[9]; /* "PXEClient" */ char vci[9]; /* "PXEClient" */
int len; int len;
uint8_t ignore_proxy = 0; uint8_t ignore_pxe = 0;
unsigned long elapsed; unsigned long elapsed;
/* Check for presence of DHCP server ID */ /* Check for presence of DHCP server ID */
@ -849,26 +851,25 @@ static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
} }
/* If there is a "PXEClient" vendor class ID, it's a /* If there is a "PXEClient" vendor class ID, it's a
* ProxyDHCPOFFER. Note that it could be both a normal * PXEDHCPOFFER. Note that it could be both a normal
* DHCPOFFER and a ProxyDHCPOFFER. * DHCPOFFER and a PXEDHCPOFFER.
*/ */
len = dhcppkt_fetch ( &dhcpoffer->dhcppkt, DHCP_VENDOR_CLASS_ID, len = dhcppkt_fetch ( &dhcpoffer->dhcppkt, DHCP_VENDOR_CLASS_ID,
vci, sizeof ( vci ) ); vci, sizeof ( vci ) );
if ( ( server_id.s_addr != 0 ) && if ( ( server_id.s_addr != 0 ) &&
( len >= ( int ) sizeof ( vci ) ) && ( len >= ( int ) sizeof ( vci ) ) &&
( strncmp ( "PXEClient", vci, sizeof ( vci ) ) == 0 ) ) { ( strncmp ( "PXEClient", vci, sizeof ( vci ) ) == 0 ) ) {
DBGC ( dhcp, "DHCP %p DHCPOFFER %p from %s is a " DBGC ( dhcp, "DHCP %p DHCPOFFER %p from %s has PXE options\n",
"ProxyDHCPOFFER\n",
dhcp, dhcpoffer, inet_ntoa ( server_id ) ); dhcp, dhcpoffer, inet_ntoa ( server_id ) );
dhcp_store_dhcpoffer ( dhcp, dhcpoffer, dhcp_store_dhcpoffer ( dhcp, dhcpoffer,
&dhcp->proxydhcpoffer ); &dhcp->pxedhcpoffer );
} }
/* We can transition to making the DHCPREQUEST when we have a /* We can transition to making the DHCPREQUEST when we have a
* valid DHCPOFFER, and either: * valid DHCPOFFER, and either:
* *
* o The DHCPOFFER instructs us to not wait for ProxyDHCP, or * o The DHCPOFFER instructs us to ignore PXEDHCPOFFERs, or
* o We have a valid ProxyDHCPOFFER, or * o We have a valid PXEDHCPOFFER, or
* o We have allowed sufficient time for ProxyDHCPOFFERs. * o We have allowed sufficient time for ProxyDHCPOFFERs.
*/ */
@ -876,20 +877,20 @@ static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
if ( ! dhcp->dhcpoffer ) if ( ! dhcp->dhcpoffer )
return; return;
/* If the DHCPOFFER instructs us to ignore ProxyDHCP, discard /* If the DHCPOFFER instructs us to ignore PXEDHCP, discard
* any ProxyDHCPOFFER * any PXEDHCPOFFER
*/ */
dhcppkt_fetch ( &dhcp->dhcpoffer->dhcppkt, DHCP_EB_NO_PROXYDHCP, dhcppkt_fetch ( &dhcp->dhcpoffer->dhcppkt, DHCP_EB_NO_PXEDHCP,
&ignore_proxy, sizeof ( ignore_proxy ) ); &ignore_pxe, sizeof ( ignore_pxe ) );
if ( ignore_proxy && dhcp->proxydhcpoffer ) { if ( ignore_pxe && dhcp->pxedhcpoffer ) {
DBGC ( dhcp, "DHCP %p discarding ProxyDHCPOFFER\n", dhcp ); DBGC ( dhcp, "DHCP %p discarding PXEDHCPOFFER\n", dhcp );
dhcpset_put ( dhcp->proxydhcpoffer ); dhcpset_put ( dhcp->pxedhcpoffer );
dhcp->proxydhcpoffer = NULL; dhcp->pxedhcpoffer = NULL;
} }
/* If we can't yet transition to DHCPREQUEST, do nothing */ /* If we can't yet transition to DHCPREQUEST, do nothing */
elapsed = ( currticks() - dhcp->start ); elapsed = ( currticks() - dhcp->start );
if ( ! ( ignore_proxy || dhcp->proxydhcpoffer || if ( ! ( ignore_pxe || dhcp->pxedhcpoffer ||
( elapsed > PROXYDHCP_WAIT_TIME ) ) ) ( elapsed > PROXYDHCP_WAIT_TIME ) ) )
return; return;
@ -978,11 +979,11 @@ static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
int rc; int rc;
/* Verify server ID matches, if present */ /* Verify server ID matches, if present */
assert ( dhcp->proxydhcpoffer != NULL ); assert ( dhcp->pxedhcpoffer != NULL );
if ( ( rc = dhcppkt_fetch ( &proxydhcpack->dhcppkt, if ( ( rc = dhcppkt_fetch ( &proxydhcpack->dhcppkt,
DHCP_SERVER_IDENTIFIER, &ack_server_id, DHCP_SERVER_IDENTIFIER, &ack_server_id,
sizeof ( ack_server_id ) ) ) > 0 ) { sizeof ( ack_server_id ) ) ) > 0 ) {
dhcppkt_fetch ( &dhcp->proxydhcpoffer->dhcppkt, dhcppkt_fetch ( &dhcp->pxedhcpoffer->dhcppkt,
DHCP_SERVER_IDENTIFIER, &offer_server_id, DHCP_SERVER_IDENTIFIER, &offer_server_id,
sizeof ( offer_server_id ) ); sizeof ( offer_server_id ) );
if ( offer_server_id.s_addr != ack_server_id.s_addr ) { if ( offer_server_id.s_addr != ack_server_id.s_addr ) {
@ -996,9 +997,9 @@ static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
/* Rename settings */ /* Rename settings */
proxydhcpack->settings.name = PROXYDHCP_SETTINGS_NAME; proxydhcpack->settings.name = PROXYDHCP_SETTINGS_NAME;
/* Record ProxyDHCPACK */ /* Record ProxyDHCPACK as PXEDHCPACK */
dhcpset_put ( dhcp->proxydhcpack ); dhcpset_put ( dhcp->pxedhcpack );
dhcp->proxydhcpack = dhcpset_get ( proxydhcpack ); dhcp->pxedhcpack = dhcpset_get ( proxydhcpack );
/* Register settings */ /* Register settings */
if ( ( rc = dhcp_store_dhcpack ( dhcp, proxydhcpack, NULL ) ) != 0 ) if ( ( rc = dhcp_store_dhcpack ( dhcp, proxydhcpack, NULL ) ) != 0 )
@ -1012,7 +1013,7 @@ static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
* Handle received BootServerDHCPACK * Handle received BootServerDHCPACK
* *
* @v dhcp DHCP session * @v dhcp DHCP session
* @v bsdhcpack Received BootServerDHCPACK * @v bsdhcpack Received BootServerDHCPACK
*/ */
static void dhcp_rx_bsdhcpack ( struct dhcp_session *dhcp, static void dhcp_rx_bsdhcpack ( struct dhcp_session *dhcp,
struct dhcp_settings *bsdhcpack ) { struct dhcp_settings *bsdhcpack ) {
@ -1021,7 +1022,7 @@ static void dhcp_rx_bsdhcpack ( struct dhcp_session *dhcp,
/* Rename settings */ /* Rename settings */
bsdhcpack->settings.name = BSDHCP_SETTINGS_NAME; bsdhcpack->settings.name = BSDHCP_SETTINGS_NAME;
/* Record ProxyDHCPACK */ /* Record BootServerDHCPACK */
assert ( dhcp->bsdhcpack == NULL ); assert ( dhcp->bsdhcpack == NULL );
dhcp->bsdhcpack = dhcpset_get ( bsdhcpack ); dhcp->bsdhcpack = dhcpset_get ( bsdhcpack );
@ -1107,12 +1108,12 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
break; break;
case DHCP_STATE_PROXYREQUEST: case DHCP_STATE_PROXYREQUEST:
if ( ( msgtype == DHCPACK ) && if ( ( msgtype == DHCPACK ) &&
( src_port == htons ( PROXYDHCP_PORT ) ) ) ( src_port == htons ( PXE_PORT ) ) )
dhcp_rx_proxydhcpack ( dhcp, dhcpset ); dhcp_rx_proxydhcpack ( dhcp, dhcpset );
break; break;
case DHCP_STATE_BSREQUEST: case DHCP_STATE_BSREQUEST:
if ( ( msgtype == DHCPACK ) && if ( ( msgtype == DHCPACK ) &&
( src_port == htons ( PROXYDHCP_PORT ) ) ) ( src_port == htons ( PXE_PORT ) ) )
dhcp_rx_bsdhcpack ( dhcp, dhcpset ); dhcp_rx_bsdhcpack ( dhcp, dhcpset );
break; break;
default: default: