[systemd-devel] [PATCH] libsystemd-network: Support setting DHCP client initial delay
Patrik Flykt
patrik.flykt at linux.intel.com
Thu Apr 3 00:28:45 PDT 2014
Section 4.4.1 in RFC 2131 says that a DHCP client SHOULD wait a
random time between one and ten seconds to desynchronize DHCP
clients on startup. This is supported such that the application
can optionally set an initial delay of approximately two and eight
seconds or leave the initial value unset relying only on any
machine specific randomness chosen for the main loop.
The maximum delay of slightly more than eight seconds was chosen
as it's more convenient to compute in addition to following RFC
2131 in spirit with a sensible margin towards the 17 years passed
since the exact wording of the document. The two second initial
delay variant was added to include a more neutral timeout hopefully
good enough on a very busy network. By default no initial delay is
added, as the implementation is geared towards maximum speed.
Thanks to Ted Lemon and to Jayson Vantul pointing out the reasons
having DHCP initial delay support.
---
src/libsystemd-network/sd-dhcp-client.c | 28 +++++++++++++++++++++++++++-
src/systemd/sd-dhcp-client.h | 9 +++++++++
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 06b2d1c..eb84708 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -37,6 +37,7 @@ struct sd_dhcp_client {
DHCPState state;
sd_event *event;
int event_priority;
+ enum sd_dhcp_client_initial_delay delay;
sd_event_source *timeout_resend;
int index;
int fd;
@@ -167,6 +168,15 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client,
return 0;
}
+int sd_dhcp_client_set_initial_delay(sd_dhcp_client *client,
+ enum sd_dhcp_client_initial_delay delay) {
+ assert_return(client, -EINVAL);
+
+ client->delay = delay;
+
+ return 0;
+}
+
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
assert_return(client, -EINVAL);
assert_return(ret, -EINVAL);
@@ -542,6 +552,7 @@ error:
static int client_initialize_events(sd_dhcp_client *client,
sd_event_io_handler_t io_callback) {
+ usec_t delay = 0;
int r;
assert(client);
@@ -560,10 +571,25 @@ static int client_initialize_events(sd_dhcp_client *client,
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT)) {
+ switch (client->delay) {
+ case DHCP_INITIAL_DELAY_DEFAULT:
+ break;
+
+ case DHCP_INITIAL_DELAY_LOW:
+ delay = random_u32() & 0x1fffff;
+ break;
+
+ case DHCP_INITIAL_DELAY_MAX:
+ delay = random_u32() & 0x7fffff;
+ break;
+ }
+ }
+
r = sd_event_add_time(client->event,
&client->timeout_resend,
CLOCK_MONOTONIC,
- 0, 0,
+ delay, 0,
client_timeout_resend, client);
if (r < 0)
goto error;
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index a60bb58..e5e8550 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -36,6 +36,12 @@ enum {
DHCP_EVENT_EXPIRED = 4,
};
+enum sd_dhcp_client_initial_delay {
+ DHCP_INITIAL_DELAY_DEFAULT = 0,
+ DHCP_INITIAL_DELAY_LOW = 2,
+ DHCP_INITIAL_DELAY_MAX = 8,
+};
+
typedef struct sd_dhcp_client sd_dhcp_client;
typedef void (*sd_dhcp_client_cb_t)(sd_dhcp_client *client, int event,
@@ -50,6 +56,9 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
int sd_dhcp_client_set_mac(sd_dhcp_client *client,
const struct ether_addr *addr);
+int sd_dhcp_client_set_initial_delay(sd_dhcp_client *client,
+ enum sd_dhcp_client_initial_delay delay);
+
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
int sd_dhcp_client_stop(sd_dhcp_client *client);
--
1.8.5.3
More information about the systemd-devel
mailing list