All of lore.kernel.org
 help / color / mirror / Atom feed
* ip=dhcp woes
@ 2016-07-28 11:26 Uwe Kleine-König
  2016-07-29  9:30 ` [PATCH 0/3] net: ipconfig: improve DHCP timeout handling Uwe Kleine-König
  0 siblings, 1 reply; 5+ messages in thread
From: Uwe Kleine-König @ 2016-07-28 11:26 UTC (permalink / raw)
  To: netdev; +Cc: kernel

Hello,

I have a machine with four network interfaces and I'm using ip=dhcp
during development on it.

in ic_dynamic the procedure is the following (assuming no successful
reply is received in time):

  timeout = 2s + random([0, 1]) s
loop:
  send bootp on 1st dev
  wait 1s
  send bootp on 2nd dev
  wait 1s
  send bootp on 3rd dev
  wait 1s
  send bootp on 4th dev
  wait timeout
  timeout = timeout * 4 / 7
  goto loop;

My problem now is: The dhcp server is reachable via the first device and
takes little more than 1s to respond. A reply must match the last sent
request to be accepted.

So the obvious questions are:

Why is only the last timeout increased for each loop? Why is there a
difference at all between the waits which results in a special casing of
the last device?

Alternatively, why not accept a reply on eth0 when eth1 has already sent
a request? Then the procedure could be:

  timeout = 2s + random([0, 1]) s
loop:
  send bootp on 1st dev
  send bootp on 2nd dev
  send bootp on 3rd dev
  send bootp on 4th dev
  wait timeout
  timeout = timeout * 4 / 7
  goto loop;

which looks more effective.

Is there anything I missed?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 0/3] net: ipconfig: improve DHCP timeout handling
  2016-07-28 11:26 ip=dhcp woes Uwe Kleine-König
@ 2016-07-29  9:30 ` Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 1/3] net: ipconfig: Add device name to debug messages Uwe Kleine-König
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Uwe Kleine-König @ 2016-07-29  9:30 UTC (permalink / raw)
  To: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy
  Cc: netdev, kernel, Mugunthan V N, Chris Friesen

Hello,

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 2513dfb83fc7 ("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.

Best regards
Uwe

Uwe Kleine-König (3):
  net: ipconfig: Add device name to debug messages
  net: ipconfig: Support using "delayed" DHCP replies
  net: ipconfig: drop inter-device timeout

 net/ipv4/ipconfig.c | 50 +++++++++++++++++++++-----------------------------
 1 file changed, 21 insertions(+), 29 deletions(-)

-- 
2.8.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] net: ipconfig: Add device name to debug messages
  2016-07-29  9:30 ` [PATCH 0/3] net: ipconfig: improve DHCP timeout handling Uwe Kleine-König
@ 2016-07-29  9:30   ` Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 2/3] net: ipconfig: Support using "delayed" DHCP replies Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 3/3] net: ipconfig: drop inter-device timeout Uwe Kleine-König
  2 siblings, 0 replies; 5+ messages in thread
From: Uwe Kleine-König @ 2016-07-29  9:30 UTC (permalink / raw)
  To: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy
  Cc: netdev, kernel, Mugunthan V N, Chris Friesen

This simplifies understanding what happens when there is more than one
device.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 net/ipv4/ipconfig.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 1d71c40eaaf3..369e4a004850 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -666,14 +666,14 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
 #ifdef IPCONFIG_DHCP
 
 static void __init
-ic_dhcp_init_options(u8 *options)
+ic_dhcp_init_options(u8 *options, struct ic_device *d)
 {
 	u8 mt = ((ic_servaddr == NONE)
 		 ? DHCPDISCOVER : DHCPREQUEST);
 	u8 *e = options;
 	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 */
 	e += 4;
@@ -857,7 +857,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
 	/* add DHCP options or BOOTP extensions */
 #ifdef IPCONFIG_DHCP
 	if (ic_proto_enabled & IC_USE_DHCP)
-		ic_dhcp_init_options(b->exten);
+		ic_dhcp_init_options(b->exten, d);
 	else
 #endif
 		ic_bootp_init_ext(b->exten);
@@ -1033,8 +1033,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
 	/* Is it a reply to our BOOTP request? */
 	if (b->op != BOOTP_REPLY ||
 	    b->xid != d->xid) {
-		net_err_ratelimited("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n",
-				    b->op, b->xid);
+		net_err_ratelimited("DHCP/BOOTP: Reply not for us on %s, op[%x] xid[%x]\n",
+				    d->dev->name, b->op, b->xid);
 		goto drop_unlock;
 	}
 
@@ -1075,7 +1075,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) {
 			case DHCPOFFER:
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] net: ipconfig: Support using "delayed" DHCP replies
  2016-07-29  9:30 ` [PATCH 0/3] net: ipconfig: improve DHCP timeout handling Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 1/3] net: ipconfig: Add device name to debug messages Uwe Kleine-König
@ 2016-07-29  9:30   ` Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 3/3] net: ipconfig: drop inter-device timeout Uwe Kleine-König
  2 siblings, 0 replies; 5+ messages in thread
From: Uwe Kleine-König @ 2016-07-29  9:30 UTC (permalink / raw)
  To: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy
  Cc: netdev, kernel, Mugunthan V N, Chris Friesen

The dhcp code only waits 1s between sending DHCP requests on different
devices and only accepts an answer for the device that sent out the last
request. Only the timeout at the end of a loop is increased iteratively
which favours only the last device. This makes it impossible to work
with a dhcp server that takes little more than 1s connected to a device
that is not the last one.

Instead of also increasing the inter-device timeout, teach the code to
handle delayed replies.

To accomplish that, make *ic_dev track the current ic_device instead of
the current net_device and adapt all users accordingly. The relevant
change then is to reset d to ic_dev on a reply to assert that the
followup request goes through the right device.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 net/ipv4/ipconfig.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 369e4a004850..5af6736bd384 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -188,7 +188,7 @@ struct ic_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)
 {
@@ -307,7 +307,7 @@ static void __init ic_close_devs(void)
 	while ((d = next)) {
 		next = d->next;
 		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);
 			dev_change_flags(dev, d->flags);
 		}
@@ -372,7 +372,7 @@ static int __init ic_setup_if(void)
 	int err;
 
 	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);
 	if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
 		pr_err("IP-Config: Unable to set interface address (%d)\n",
@@ -396,7 +396,7 @@ static int __init ic_setup_if(void)
 	 * out, we'll try to muddle along.
 	 */
 	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;
 		if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
 			pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n",
@@ -568,7 +568,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 		goto drop_unlock;
 
 	/* We have a winner! */
-	ic_dev = dev;
+	ic_dev = d;
 	if (ic_myaddr == NONE)
 		ic_myaddr = tip;
 	ic_servaddr = sip;
@@ -655,8 +655,6 @@ static struct packet_type bootp_packet_type __initdata = {
 	.func =	ic_bootp_recv,
 };
 
-static __be32 ic_dev_xid;		/* Device under configuration */
-
 /*
  *  Initialize DHCP/BOOTP extension fields in the request.
  */
@@ -1038,12 +1036,6 @@ 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) {
-		net_err_ratelimited("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 */
@@ -1130,7 +1122,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
 	}
 
 	/* We have a winner! */
-	ic_dev = dev;
+	ic_dev = d;
 	ic_myaddr = b->your_ip;
 	ic_servaddr = b->server_ip;
 	ic_addrservaddr = b->iph.saddr;
@@ -1225,9 +1217,6 @@ static int __init ic_dynamic(void)
 	timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned int) CONF_TIMEOUT_RANDOM);
 	for (;;) {
 #ifdef IPCONFIG_BOOTP
-		/* Track the device we are configuring */
-		ic_dev_xid = d->xid;
-
 		if (do_bootp && (d->able & IC_BOOTP))
 			ic_bootp_send_if(d, jiffies - start_jiffies);
 #endif
@@ -1245,6 +1234,8 @@ static int __init ic_dynamic(void)
 		    (ic_proto_enabled & IC_USE_DHCP) &&
 		    ic_dhcp_msgtype != DHCPACK) {
 			ic_got_reply = 0;
+			/* continue on device that got the reply */
+			d = ic_dev;
 			pr_cont(",");
 			continue;
 		}
@@ -1487,7 +1478,7 @@ static int __init ip_auto_config(void)
 #endif /* IPCONFIG_DYNAMIC */
 	} else {
 		/* 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);
@@ -1522,7 +1513,7 @@ static int __init ip_auto_config(void)
 	pr_info("IP-Config: Complete:\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);
 	pr_info("     host=%s, domain=%s, nis-domain=%s\n",
 		utsname()->nodename, ic_domain, utsname()->domainname);
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] net: ipconfig: drop inter-device timeout
  2016-07-29  9:30 ` [PATCH 0/3] net: ipconfig: improve DHCP timeout handling Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 1/3] net: ipconfig: Add device name to debug messages Uwe Kleine-König
  2016-07-29  9:30   ` [PATCH 2/3] net: ipconfig: Support using "delayed" DHCP replies Uwe Kleine-König
@ 2016-07-29  9:30   ` Uwe Kleine-König
  2 siblings, 0 replies; 5+ messages in thread
From: Uwe Kleine-König @ 2016-07-29  9:30 UTC (permalink / raw)
  To: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy
  Cc: netdev, kernel, Mugunthan V N, Chris Friesen

Now that ipconfig learned to handle "delayed replies" in the previous
commit, there is no reason any more to delay sending a first request per
device.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 net/ipv4/ipconfig.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 5af6736bd384..42cf629357b5 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -85,7 +85,6 @@
 /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
 #define CONF_OPEN_RETRIES 	2	/* (Re)open devices twice */
 #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_TIMEOUT_RANDOM	(HZ)	/* Maximum amount of randomization */
 #define CONF_TIMEOUT_MULT	*7/4	/* Rate of timeout growth */
@@ -1225,9 +1224,11 @@ static int __init ic_dynamic(void)
 			ic_rarp_send_if(d);
 #endif
 
-		jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
-		while (time_before(jiffies, jiff) && !ic_got_reply)
-			schedule_timeout_uninterruptible(1);
+		if (!d->next) {
+			jiff = jiffies + timeout;
+			while (time_before(jiffies, jiff) && !ic_got_reply)
+				schedule_timeout_uninterruptible(1);
+		}
 #ifdef IPCONFIG_DHCP
 		/* DHCP isn't done until we get a DHCPACK. */
 		if ((ic_got_reply & IC_BOOTP) &&
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-07-29  9:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-28 11:26 ip=dhcp woes Uwe Kleine-König
2016-07-29  9:30 ` [PATCH 0/3] net: ipconfig: improve DHCP timeout handling Uwe Kleine-König
2016-07-29  9:30   ` [PATCH 1/3] net: ipconfig: Add device name to debug messages Uwe Kleine-König
2016-07-29  9:30   ` [PATCH 2/3] net: ipconfig: Support using "delayed" DHCP replies Uwe Kleine-König
2016-07-29  9:30   ` [PATCH 3/3] net: ipconfig: drop inter-device timeout Uwe Kleine-König

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.