Commit 2513dfb8 authored by Chris Friesen's avatar Chris Friesen Committed by David S. Miller

ipconfig: handle case of delayed DHCP server

If a DHCP server is delayed, it's possible for the client to receive the 
DHCPOFFER after it has already sent out a new DHCPDISCOVER message from 
a second interface.  The client then sends out a DHCPREQUEST from the 
second interface, but the server doesn't recognize the device and 
rejects the request.

This patch simply tracks the current device being configured and throws 
away the OFFER if it is not intended for the current device.  A more 
sophisticated approach would be to put the OFFER information into the 
struct ic_device rather than storing it globally.
Signed-off-by: default avatarChris Friesen <cfriesen@nortel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5e392739
...@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE; /* Boot server IP address */ ...@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE; /* Boot server IP address */
__be32 root_server_addr = NONE; /* Address of NFS server */ __be32 root_server_addr = NONE; /* Address of NFS server */
u8 root_server_path[256] = { 0, }; /* Path to mount as root */ u8 root_server_path[256] = { 0, }; /* Path to mount as root */
u32 ic_dev_xid; /* Device under configuration */
/* vendor class identifier */ /* vendor class identifier */
static char vendor_class_identifier[253] __initdata; static char vendor_class_identifier[253] __initdata;
...@@ -932,6 +934,13 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str ...@@ -932,6 +934,13 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
goto drop_unlock; goto drop_unlock;
} }
/* Is it a reply for the device we are configuring? */
if (b->xid != ic_dev_xid) {
if (net_ratelimit())
printk(KERN_ERR "DHCP/BOOTP: Ignoring delayed packet \n");
goto drop_unlock;
}
/* Parse extensions */ /* Parse extensions */
if (ext_len >= 4 && if (ext_len >= 4 &&
!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */ !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
...@@ -1115,6 +1124,9 @@ static int __init ic_dynamic(void) ...@@ -1115,6 +1124,9 @@ static int __init ic_dynamic(void)
get_random_bytes(&timeout, sizeof(timeout)); get_random_bytes(&timeout, sizeof(timeout));
timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM); timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
for (;;) { for (;;) {
/* Track the device we are configuring */
ic_dev_xid = d->xid;
#ifdef IPCONFIG_BOOTP #ifdef IPCONFIG_BOOTP
if (do_bootp && (d->able & IC_BOOTP)) if (do_bootp && (d->able & IC_BOOTP))
ic_bootp_send_if(d, jiffies - start_jiffies); ic_bootp_send_if(d, jiffies - start_jiffies);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment