summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChris Friesen <cfriesen@nortel.com>2009-05-17 20:39:33 -0700
committerDavid S. Miller <davem@davemloft.net>2009-05-17 20:39:33 -0700
commit2513dfb83fc775364fe85803d3a84d7ebe5763a5 (patch)
tree157003b5c1b88c1eb95b1307db9835ddd610fb02 /net
parent5e392739d6ab72f7c35040aa07f4097904bce6e7 (diff)
downloadlinux-2513dfb83fc775364fe85803d3a84d7ebe5763a5.tar.bz2
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: Chris Friesen <cfriesen@nortel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/ipconfig.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 90d22ae0a419..88bf051d0cbb 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE; /* Boot server IP address */
__be32 root_server_addr = NONE; /* Address of NFS server */
u8 root_server_path[256] = { 0, }; /* Path to mount as root */
+u32 ic_dev_xid; /* Device under configuration */
+
/* vendor class identifier */
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
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 */
if (ext_len >= 4 &&
!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
@@ -1115,6 +1124,9 @@ static int __init ic_dynamic(void)
get_random_bytes(&timeout, sizeof(timeout));
timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
for (;;) {
+ /* Track the device we are configuring */
+ ic_dev_xid = d->xid;
+
#ifdef IPCONFIG_BOOTP
if (do_bootp && (d->able & IC_BOOTP))
ic_bootp_send_if(d, jiffies - start_jiffies);