[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 5/9] net: dhcp: introduce per-interface timeout
From: |
Andre Przywara |
Subject: |
[PATCH v2 5/9] net: dhcp: introduce per-interface timeout |
Date: |
Tue, 12 Feb 2019 17:46:56 +0000 |
From: Andrei Borzenkov <address@hidden>
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 <address@hidden>
---
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
- [PATCH v2 0/9] net: bootp: add native DHCPv4 support, Andre Przywara, 2019/02/12
- [PATCH v2 1/9] net: dhcp: remove dead code, Andre Przywara, 2019/02/12
- [PATCH v2 2/9] net: dhcp: replace parse_dhcp_vendor() with find_dhcp_option(), Andre Przywara, 2019/02/12
- [PATCH v2 3/9] net: dhcp: refactor DHCP packet transmission into separate function, Andre Przywara, 2019/02/12
- [PATCH v2 4/9] net: dhcp: make grub_net_process_dhcp take an interface, Andre Przywara, 2019/02/12
- [PATCH v2 5/9] net: dhcp: introduce per-interface timeout,
Andre Przywara <=
- [PATCH v2 6/9] net: dhcp: use DHCP options for name and bootfile, Andre Przywara, 2019/02/12
- [PATCH v2 8/9] net: dhcp: actually send out DHCPv4 DISCOVER and REQUEST messages, Andre Przywara, 2019/02/12
- [PATCH v2 7/9] net: dhcp: allow receiving DHCP OFFER and ACK packets, Andre Przywara, 2019/02/12
- [PATCH v2 9/9] net: dhcp: add explicit net_dhcp command, Andre Przywara, 2019/02/12