From fb809da2dfe9d715a02de7033ede46854d176c2e Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 21 Nov 2007 04:48:18 +0000 Subject: [PATCH] Remove some assumptions about DHCP obtaining only a single options block. --- src/include/gpxe/dhcp.h | 2 ++ src/net/dhcpopts.c | 6 +++--- src/net/udp/dhcp.c | 10 +++++++--- src/usr/dhcpmgmt.c | 19 +++++++++++-------- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/include/gpxe/dhcp.h b/src/include/gpxe/dhcp.h index b5923fd2..60d2ccff 100644 --- a/src/include/gpxe/dhcp.h +++ b/src/include/gpxe/dhcp.h @@ -512,6 +512,8 @@ dhcpopt_put ( struct dhcp_option_block *options ) { ref_put ( &options->refcnt ); } +extern struct list_head dhcp_option_blocks; + extern unsigned long dhcp_num_option ( struct dhcp_option *option ); extern void dhcp_ipv4_option ( struct dhcp_option *option, struct in_addr *inp ); diff --git a/src/net/dhcpopts.c b/src/net/dhcpopts.c index c713909e..d1837be3 100644 --- a/src/net/dhcpopts.c +++ b/src/net/dhcpopts.c @@ -35,7 +35,7 @@ */ /** List of registered DHCP option blocks */ -static LIST_HEAD ( option_blocks ); +LIST_HEAD ( dhcp_option_blocks ); /** Registered DHCP option applicators */ static struct dhcp_option_applicator dhcp_option_applicators[0] @@ -259,7 +259,7 @@ struct dhcp_option * find_dhcp_option ( struct dhcp_option_block *options, if ( options ) { return find_dhcp_option_with_encap ( options, tag, NULL ); } else { - list_for_each_entry ( options, &option_blocks, list ) { + list_for_each_entry ( options, &dhcp_option_blocks, list ) { if ( ( option = find_dhcp_option ( options, tag ) ) ) return option; } @@ -283,7 +283,7 @@ void register_dhcp_options ( struct dhcp_option_block *options ) { options, options->priority ); /* Insert after any existing blocks which have a higher priority */ - list_for_each_entry ( existing, &option_blocks, list ) { + list_for_each_entry ( existing, &dhcp_option_blocks, list ) { if ( options->priority > existing->priority ) break; } diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 7de05ac1..30804457 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -1006,14 +1006,18 @@ int dhcp_configure_netdev ( struct net_device *netdev, struct in_addr gateway = { INADDR_NONE }; int rc; - /* Clear any existing routing table entry */ - del_ipv4_address ( netdev ); - /* Retrieve IP address configuration */ find_dhcp_ipv4_option ( options, DHCP_EB_YIADDR, &address ); find_dhcp_ipv4_option ( options, DHCP_SUBNET_MASK, &netmask ); find_dhcp_ipv4_option ( options, DHCP_ROUTERS, &gateway ); + /* Do nothing unless we have at least an IP address to use */ + if ( ! address.s_addr ) + return 0; + + /* Clear any existing routing table entry */ + del_ipv4_address ( netdev ); + /* Set up new IP address configuration */ if ( ( rc = add_ipv4_address ( netdev, address, netmask, gateway ) ) != 0 ) { diff --git a/src/usr/dhcpmgmt.c b/src/usr/dhcpmgmt.c index bd05c5ee..0c6b4588 100644 --- a/src/usr/dhcpmgmt.c +++ b/src/usr/dhcpmgmt.c @@ -32,27 +32,30 @@ * */ -static struct dhcp_option_block *dhcp_options = NULL; - static int dhcp_success ( struct net_device *netdev, struct dhcp_option_block *options ) { - dhcp_options = dhcpopt_get ( options ); + DBGC ( options, "DHCP client registering options %p\n", options ); register_dhcp_options ( options ); return dhcp_configure_netdev ( netdev, options ); } int dhcp ( struct net_device *netdev ) { + struct dhcp_option_block *options; + struct dhcp_option_block *tmp; int rc; /* Check we can open the interface first */ if ( ( rc = ifopen ( netdev ) ) != 0 ) return rc; - /* Unregister any previously acquired options */ - if ( dhcp_options ) { - unregister_dhcp_options ( dhcp_options ); - dhcpopt_put ( dhcp_options ); - dhcp_options = NULL; + /* Unregister any option blocks acquired via DHCP */ + list_for_each_entry_safe ( options, tmp, &dhcp_option_blocks, list ) { + /* Skip static option blocks (e.g. from NVS) */ + if ( find_dhcp_option ( options, DHCP_MESSAGE_TYPE ) ) { + DBGC ( options, "DHCP client unregistering options " + "%p\n", options ); + unregister_dhcp_options ( options ); + } } /* Perform DHCP */