All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Daniel Kiper <dkiper@net-space.pl>
Cc: Vladimir Serbinenko <phcoder@gmail.com>,
	Andrei Borzenkov <arvidjaar@gmail.com>,
	Daniel Kiper <daniel.kiper@oracle.com>,
	Mark Rutland <mark.rutland@arm.com>,
	grub-devel@gnu.org
Subject: [PATCH v2 5/9] net: dhcp: introduce per-interface timeout
Date: Tue, 12 Feb 2019 17:46:56 +0000	[thread overview]
Message-ID: <20190212174700.184741-6-andre.przywara@arm.com> (raw)
In-Reply-To: <20190212174700.184741-1-andre.przywara@arm.com>

From: Andrei Borzenkov <arvidjaar@gmail.com>

Currently we have a global timeout for all network cards in the
BOOTP/DHCP discovery process.

Make this timeout a per-interface one, so better accommodate the
upcoming 4-way DHCP handshake and to also cover the lease time limit a
DHCP offer will come with.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 grub-core/net/bootp.c | 38 ++++++++++++++++++++++++++++++++++----
 include/grub/net.h    |  2 ++
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 573398aa4..42117b72d 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -33,6 +33,9 @@ enum
 
 #define GRUB_BOOTP_MAX_OPTIONS_SIZE 64
 
+/* Max timeout when waiting for BOOTP/DHCP reply */
+#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32
+
 static const void *
 find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size,
 		  grub_uint8_t opt_code, grub_uint8_t *opt_len)
@@ -553,7 +556,6 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
   struct grub_net_network_level_interface *ifaces;
   grub_size_t ncards = 0;
   unsigned j = 0;
-  int interval;
   grub_err_t err;
   unsigned i;
 
@@ -592,6 +594,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
     ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV;
     grub_memcpy (&ifaces[j].hwaddress, &card->default_address, 
 		 sizeof (ifaces[j].hwaddress));
+    ifaces[j].dhcp_tmo = ifaces[j].dhcp_tmo_left = 1;
     j++;
   }
   ifaces[ncards - 1].next = grub_net_network_level_interfaces;
@@ -599,25 +602,52 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
     grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next;
   grub_net_network_level_interfaces = &ifaces[0];
   ifaces[0].prev = &grub_net_network_level_interfaces;
-  for (interval = 200; interval < 10000; interval *= 2)
+
+  /*
+   * Running DHCP restransmission timer is kept per interface in dhcp_tmo_left.
+   * When it runs off, dhcp_tmo is increased exponentionally and dhcp_tmo_left
+   * initialized to it. Max value is 32 which gives approximately 12s total per
+   * packet timeout assuming 200ms poll tick. Timeout is reset when DHCP OFFER
+   * is received, so total timeout is 25s in the worst case.
+   *
+   * DHCP NAK also resets timer and transaction starts again.
+   *
+   * Total wait time is limited to ~25s to prevent endless loop in case of
+   * permanent NAK
+   */
+  for (i = 0; i < GRUB_DHCP_MAX_PACKET_TIMEOUT * 4; i++)
     {
       int need_poll = 0;
       for (j = 0; j < ncards; j++)
 	{
-	  if (!ifaces[j].prev)
+	  if (!ifaces[j].prev ||
+             ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT)
+	    continue;
+
+	  if (--ifaces[j].dhcp_tmo_left)
+	    {
+	      need_poll = 1;
+	      continue;
+	    }
+
+	  ifaces[j].dhcp_tmo *= 2;
+	  if (ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT)
 	    continue;
 
 	  err = send_dhcp_packet (&ifaces[j]);
 	  if (err)
 	    {
 	      grub_print_error ();
+	      /* To ignore it during next poll */
+	      ifaces[j].dhcp_tmo = GRUB_DHCP_MAX_PACKET_TIMEOUT + 1;
 	      continue;
 	    }
+	  ifaces[j].dhcp_tmo_left = ifaces[j].dhcp_tmo;
 	  need_poll = 1;
 	}
       if (!need_poll)
 	break;
-      grub_net_poll_cards (interval, 0);
+      grub_net_poll_cards (200, 0);
     }
 
   err = GRUB_ERR_NONE;
diff --git a/include/grub/net.h b/include/grub/net.h
index 3f649d753..a1138f5d4 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -292,6 +292,8 @@ struct grub_net_network_level_interface
   struct grub_net_bootp_packet *dhcp_ack;
   grub_size_t dhcp_acklen;
   grub_uint16_t vlantag;
+  unsigned dhcp_tmo_left; /* DHCPv4 running retransmission timeout */
+  unsigned dhcp_tmo;      /* DHCPv4 current retransmission timeout */
   void *data;
 };
 
-- 
2.17.1



  parent reply	other threads:[~2019-02-12 17:47 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-12 17:46 [PATCH v2 0/9] net: bootp: add native DHCPv4 support Andre Przywara
2019-02-12 17:46 ` [PATCH v2 1/9] net: dhcp: remove dead code Andre Przywara
2019-02-20 21:09   ` Daniel Kiper
2019-02-12 17:46 ` [PATCH v2 2/9] net: dhcp: replace parse_dhcp_vendor() with find_dhcp_option() Andre Przywara
2019-02-21 18:06   ` Daniel Kiper
2019-02-12 17:46 ` [PATCH v2 3/9] net: dhcp: refactor DHCP packet transmission into separate function Andre Przywara
2019-02-21 18:12   ` Daniel Kiper
2019-02-12 17:46 ` [PATCH v2 4/9] net: dhcp: make grub_net_process_dhcp take an interface Andre Przywara
2019-02-21 18:21   ` Daniel Kiper
2019-02-12 17:46 ` Andre Przywara [this message]
2019-02-21 18:40   ` [PATCH v2 5/9] net: dhcp: introduce per-interface timeout Daniel Kiper
2019-02-12 17:46 ` [PATCH v2 6/9] net: dhcp: use DHCP options for name and bootfile Andre Przywara
2019-02-21 18:49   ` Daniel Kiper
2019-03-07 10:36     ` Andre Przywara
2019-02-12 17:46 ` [PATCH v2 7/9] net: dhcp: allow receiving DHCP OFFER and ACK packets Andre Przywara
2019-02-21 22:11   ` Daniel Kiper
2019-02-12 17:46 ` [PATCH v2 8/9] net: dhcp: actually send out DHCPv4 DISCOVER and REQUEST messages Andre Przywara
2019-02-21 22:19   ` Daniel Kiper
2019-02-12 17:47 ` [PATCH v2 9/9] net: dhcp: add explicit net_dhcp command Andre Przywara
2019-02-21 22:28   ` Daniel Kiper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190212174700.184741-6-andre.przywara@arm.com \
    --to=andre.przywara@arm.com \
    --cc=arvidjaar@gmail.com \
    --cc=daniel.kiper@oracle.com \
    --cc=dkiper@net-space.pl \
    --cc=grub-devel@gnu.org \
    --cc=mark.rutland@arm.com \
    --cc=phcoder@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.