Commit 9f3377ef authored by David S. Miller's avatar David S. Miller

Merge branch 'ipconfig-improve-dhcp-timeouts'

Uwe Kleine-König says:

====================
net: ipconfig: improve DHCP timeout handling

this series teaches the ipconfig code to handle a DHCP reply on eth0 even if a
request on eth1 was already sent out.
This is a follow fix to 2513dfb8 ("ipconfig: handle case of delayed DHCP
server") that dropped a late reply.

This makes it possible at all to work with slow DHCP servers at all in some
configurations and improves boot speed in general.

The first patch is not really necessary, it only helps decoding debug messages
when there is more than one device.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 874e1b75 e0688534
...@@ -85,7 +85,6 @@ ...@@ -85,7 +85,6 @@
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */ /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */ #define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
#define CONF_SEND_RETRIES 6 /* Send six requests per open */ #define CONF_SEND_RETRIES 6 /* Send six requests per open */
#define CONF_INTER_TIMEOUT (HZ) /* Inter-device timeout: 1 second */
#define CONF_BASE_TIMEOUT (HZ*2) /* Initial timeout: 2 seconds */ #define CONF_BASE_TIMEOUT (HZ*2) /* Initial timeout: 2 seconds */
#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */ #define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */ #define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */
...@@ -188,7 +187,7 @@ struct ic_device { ...@@ -188,7 +187,7 @@ struct ic_device {
}; };
static struct ic_device *ic_first_dev __initdata; /* List of open device */ static struct ic_device *ic_first_dev __initdata; /* List of open device */
static struct net_device *ic_dev __initdata; /* Selected device */ static struct ic_device *ic_dev __initdata; /* Selected device */
static bool __init ic_is_init_dev(struct net_device *dev) static bool __init ic_is_init_dev(struct net_device *dev)
{ {
...@@ -307,7 +306,7 @@ static void __init ic_close_devs(void) ...@@ -307,7 +306,7 @@ static void __init ic_close_devs(void)
while ((d = next)) { while ((d = next)) {
next = d->next; next = d->next;
dev = d->dev; dev = d->dev;
if (dev != ic_dev && !netdev_uses_dsa(dev)) { if (dev != ic_dev->dev && !netdev_uses_dsa(dev)) {
pr_debug("IP-Config: Downing %s\n", dev->name); pr_debug("IP-Config: Downing %s\n", dev->name);
dev_change_flags(dev, d->flags); dev_change_flags(dev, d->flags);
} }
...@@ -372,7 +371,7 @@ static int __init ic_setup_if(void) ...@@ -372,7 +371,7 @@ static int __init ic_setup_if(void)
int err; int err;
memset(&ir, 0, sizeof(ir)); memset(&ir, 0, sizeof(ir));
strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name); strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->dev->name);
set_sockaddr(sin, ic_myaddr, 0); set_sockaddr(sin, ic_myaddr, 0);
if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) { if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
pr_err("IP-Config: Unable to set interface address (%d)\n", pr_err("IP-Config: Unable to set interface address (%d)\n",
...@@ -396,7 +395,7 @@ static int __init ic_setup_if(void) ...@@ -396,7 +395,7 @@ static int __init ic_setup_if(void)
* out, we'll try to muddle along. * out, we'll try to muddle along.
*/ */
if (ic_dev_mtu != 0) { if (ic_dev_mtu != 0) {
strcpy(ir.ifr_name, ic_dev->name); strcpy(ir.ifr_name, ic_dev->dev->name);
ir.ifr_mtu = ic_dev_mtu; ir.ifr_mtu = ic_dev_mtu;
if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0) if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n", pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n",
...@@ -568,7 +567,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ...@@ -568,7 +567,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
goto drop_unlock; goto drop_unlock;
/* We have a winner! */ /* We have a winner! */
ic_dev = dev; ic_dev = d;
if (ic_myaddr == NONE) if (ic_myaddr == NONE)
ic_myaddr = tip; ic_myaddr = tip;
ic_servaddr = sip; ic_servaddr = sip;
...@@ -655,8 +654,6 @@ static struct packet_type bootp_packet_type __initdata = { ...@@ -655,8 +654,6 @@ static struct packet_type bootp_packet_type __initdata = {
.func = ic_bootp_recv, .func = ic_bootp_recv,
}; };
static __be32 ic_dev_xid; /* Device under configuration */
/* /*
* Initialize DHCP/BOOTP extension fields in the request. * Initialize DHCP/BOOTP extension fields in the request.
*/ */
...@@ -666,14 +663,14 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 }; ...@@ -666,14 +663,14 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
#ifdef IPCONFIG_DHCP #ifdef IPCONFIG_DHCP
static void __init static void __init
ic_dhcp_init_options(u8 *options) ic_dhcp_init_options(u8 *options, struct ic_device *d)
{ {
u8 mt = ((ic_servaddr == NONE) u8 mt = ((ic_servaddr == NONE)
? DHCPDISCOVER : DHCPREQUEST); ? DHCPDISCOVER : DHCPREQUEST);
u8 *e = options; u8 *e = options;
int len; int len;
pr_debug("DHCP: Sending message type %d\n", mt); pr_debug("DHCP: Sending message type %d (%s)\n", mt, d->dev->name);
memcpy(e, ic_bootp_cookie, 4); /* RFC1048 Magic Cookie */ memcpy(e, ic_bootp_cookie, 4); /* RFC1048 Magic Cookie */
e += 4; e += 4;
...@@ -857,7 +854,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d ...@@ -857,7 +854,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
/* add DHCP options or BOOTP extensions */ /* add DHCP options or BOOTP extensions */
#ifdef IPCONFIG_DHCP #ifdef IPCONFIG_DHCP
if (ic_proto_enabled & IC_USE_DHCP) if (ic_proto_enabled & IC_USE_DHCP)
ic_dhcp_init_options(b->exten); ic_dhcp_init_options(b->exten, d);
else else
#endif #endif
ic_bootp_init_ext(b->exten); ic_bootp_init_ext(b->exten);
...@@ -1033,14 +1030,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str ...@@ -1033,14 +1030,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
/* Is it a reply to our BOOTP request? */ /* Is it a reply to our BOOTP request? */
if (b->op != BOOTP_REPLY || if (b->op != BOOTP_REPLY ||
b->xid != d->xid) { b->xid != d->xid) {
net_err_ratelimited("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n", net_err_ratelimited("DHCP/BOOTP: Reply not for us on %s, op[%x] xid[%x]\n",
b->op, b->xid); d->dev->name, b->op, b->xid);
goto drop_unlock;
}
/* Is it a reply for the device we are configuring? */
if (b->xid != ic_dev_xid) {
net_err_ratelimited("DHCP/BOOTP: Ignoring delayed packet\n");
goto drop_unlock; goto drop_unlock;
} }
...@@ -1075,7 +1066,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str ...@@ -1075,7 +1066,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
} }
} }
pr_debug("DHCP: Got message type %d\n", mt); pr_debug("DHCP: Got message type %d (%s)\n", mt, d->dev->name);
switch (mt) { switch (mt) {
case DHCPOFFER: case DHCPOFFER:
...@@ -1130,7 +1121,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str ...@@ -1130,7 +1121,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
} }
/* We have a winner! */ /* We have a winner! */
ic_dev = dev; ic_dev = d;
ic_myaddr = b->your_ip; ic_myaddr = b->your_ip;
ic_servaddr = b->server_ip; ic_servaddr = b->server_ip;
ic_addrservaddr = b->iph.saddr; ic_addrservaddr = b->iph.saddr;
...@@ -1225,9 +1216,6 @@ static int __init ic_dynamic(void) ...@@ -1225,9 +1216,6 @@ static int __init ic_dynamic(void)
timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned int) CONF_TIMEOUT_RANDOM); timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned int) CONF_TIMEOUT_RANDOM);
for (;;) { for (;;) {
#ifdef IPCONFIG_BOOTP #ifdef IPCONFIG_BOOTP
/* Track the device we are configuring */
ic_dev_xid = d->xid;
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);
#endif #endif
...@@ -1236,15 +1224,19 @@ static int __init ic_dynamic(void) ...@@ -1236,15 +1224,19 @@ static int __init ic_dynamic(void)
ic_rarp_send_if(d); ic_rarp_send_if(d);
#endif #endif
jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout); if (!d->next) {
jiff = jiffies + timeout;
while (time_before(jiffies, jiff) && !ic_got_reply) while (time_before(jiffies, jiff) && !ic_got_reply)
schedule_timeout_uninterruptible(1); schedule_timeout_uninterruptible(1);
}
#ifdef IPCONFIG_DHCP #ifdef IPCONFIG_DHCP
/* DHCP isn't done until we get a DHCPACK. */ /* DHCP isn't done until we get a DHCPACK. */
if ((ic_got_reply & IC_BOOTP) && if ((ic_got_reply & IC_BOOTP) &&
(ic_proto_enabled & IC_USE_DHCP) && (ic_proto_enabled & IC_USE_DHCP) &&
ic_dhcp_msgtype != DHCPACK) { ic_dhcp_msgtype != DHCPACK) {
ic_got_reply = 0; ic_got_reply = 0;
/* continue on device that got the reply */
d = ic_dev;
pr_cont(","); pr_cont(",");
continue; continue;
} }
...@@ -1487,7 +1479,7 @@ static int __init ip_auto_config(void) ...@@ -1487,7 +1479,7 @@ static int __init ip_auto_config(void)
#endif /* IPCONFIG_DYNAMIC */ #endif /* IPCONFIG_DYNAMIC */
} else { } else {
/* Device selected manually or only one device -> use it */ /* Device selected manually or only one device -> use it */
ic_dev = ic_first_dev->dev; ic_dev = ic_first_dev;
} }
addr = root_nfs_parse_addr(root_server_path); addr = root_nfs_parse_addr(root_server_path);
...@@ -1522,7 +1514,7 @@ static int __init ip_auto_config(void) ...@@ -1522,7 +1514,7 @@ static int __init ip_auto_config(void)
pr_info("IP-Config: Complete:\n"); pr_info("IP-Config: Complete:\n");
pr_info(" device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n", pr_info(" device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n",
ic_dev->name, ic_dev->addr_len, ic_dev->dev_addr, ic_dev->dev->name, ic_dev->dev->addr_len, ic_dev->dev->dev_addr,
&ic_myaddr, &ic_netmask, &ic_gateway); &ic_myaddr, &ic_netmask, &ic_gateway);
pr_info(" host=%s, domain=%s, nis-domain=%s\n", pr_info(" host=%s, domain=%s, nis-domain=%s\n",
utsname()->nodename, ic_domain, utsname()->domainname); utsname()->nodename, ic_domain, utsname()->domainname);
......
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