summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-11-08 04:20:17 +0100
committerGitHub <noreply@github.com>2023-11-08 04:20:17 +0100
commitb2622db0df5bcd82529a781ed1209f8ddeb18f8e (patch)
tree2259ba415687489c6b4cfdf909dbb90f349a8817
parentMerge pull request #29913 from keszybz/vmspawn-ci (diff)
parentnetwork: add [DHCPServer] RapidCommit= setting (diff)
downloadsystemd-b2622db0df5bcd82529a781ed1209f8ddeb18f8e.tar.xz
systemd-b2622db0df5bcd82529a781ed1209f8ddeb18f8e.zip
Merge pull request #29910 from yuwata/rapid-commit
dhcp: about rapid commit
-rw-r--r--man/systemd.network.xml12
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h2
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c5
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c27
-rw-r--r--src/network/networkd-dhcp-server.c5
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c1
-rw-r--r--src/network/networkd-network.h1
-rw-r--r--src/systemd/sd-dhcp-server.h1
9 files changed, 52 insertions, 3 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 3e83caaf18..fe8c8a14c6 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -3768,6 +3768,18 @@ ServerAddress=192.168.0.1/24</programlisting>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>RapidCommit=</varname></term>
+ <listitem>
+ <para>Takes a boolean. When true, the server supports
+ <ulink url="https://datatracker.ietf.org/doc/html/rfc4039">RFC 4039</ulink>. When a client sends
+ a DHCPDISCOVER message with the Rapid Commit option to the server, then the server will reply with
+ a DHCPACK message to the client, instead of DHCPOFFER. Defaults to true.</para>
+
+ <xi:include href="version-info.xml" xpointer="v255"/>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index 1879b5b159..8db517293f 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -84,6 +84,7 @@ struct sd_dhcp_server {
usec_t max_lease_time;
usec_t default_lease_time;
usec_t ipv6_only_preferred_usec;
+ bool rapid_commit;
sd_dhcp_server_callback_t callback;
void *callback_userdata;
@@ -108,6 +109,7 @@ typedef struct DHCPRequest {
char *hostname;
const uint8_t *parameter_request_list;
size_t parameter_request_list_len;
+ bool rapid_commit;
} DHCPRequest;
extern const struct hash_ops dhcp_lease_hash_ops;
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 8a94685ba7..bbe0b5227b 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1367,6 +1367,7 @@ static int client_timeout_resend(
} else if (client->attempt >= client->max_attempts)
goto error;
+ client->request_sent = time_now;
break;
case DHCP_STATE_SELECTING:
@@ -1374,9 +1375,7 @@ static int client_timeout_resend(
if (r < 0 && client->attempt >= client->max_attempts)
goto error;
- if (client->rapid_commit)
- client->request_sent = time_now;
-
+ client->request_sent = time_now;
break;
case DHCP_STATE_INIT_REBOOT:
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 54a659766d..437028800d 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -211,6 +211,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
.bind_to_interface = true,
.default_lease_time = DHCP_DEFAULT_LEASE_TIME_USEC,
.max_lease_time = DHCP_MAX_LEASE_TIME_USEC,
+ .rapid_commit = true,
};
*ret = TAKE_PTR(server);
@@ -692,6 +693,15 @@ static int server_send_offer_or_ack(
return r;
}
+ if (server->rapid_commit && req->rapid_commit && type == DHCP_ACK) {
+ r = dhcp_option_append(
+ &packet->dhcp, req->max_optlen, &offset, 0,
+ SD_DHCP_OPTION_RAPID_COMMIT,
+ 0, NULL);
+ if (r < 0)
+ return r;
+ }
+
return dhcp_server_send_packet(server, req, packet, type, offset);
}
@@ -810,6 +820,10 @@ static int parse_request(uint8_t code, uint8_t len, const void *option, void *us
req->parameter_request_list = option;
req->parameter_request_list_len = len;
break;
+
+ case SD_DHCP_OPTION_RAPID_COMMIT:
+ req->rapid_commit = true;
+ break;
}
return 0;
@@ -1210,6 +1224,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
/* no free addresses left */
return 0;
+ if (server->rapid_commit && req->rapid_commit)
+ return server_ack_request(server, req, existing_lease, address);
+
r = server_send_offer_or_ack(server, req, address, DHCP_OFFER);
if (r < 0)
/* this only fails on critical errors */
@@ -1274,6 +1291,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
address = req->message->ciaddr;
}
+ /* Silently ignore Rapid Commit option in REQUEST message. */
+ req->rapid_commit = false;
+
/* disallow our own address */
if (address == server->address)
return 0;
@@ -1545,6 +1565,13 @@ int sd_dhcp_server_set_ipv6_only_preferred_usec(sd_dhcp_server *server, uint64_t
return 0;
}
+int sd_dhcp_server_set_rapid_commit(sd_dhcp_server *server, int enabled) {
+ assert_return(server, -EINVAL);
+
+ server->rapid_commit = enabled;
+ return 0;
+}
+
int sd_dhcp_server_set_servers(
sd_dhcp_server *server,
sd_dhcp_lease_server_type_t what,
diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c
index 17939ce54a..607fe0053c 100644
--- a/src/network/networkd-dhcp-server.c
+++ b/src/network/networkd-dhcp-server.c
@@ -418,6 +418,11 @@ static int dhcp4_server_configure(Link *link) {
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set boot filename for DHCPv4 server instance: %m");
+ r = sd_dhcp_server_set_rapid_commit(link->dhcp_server, link->network->dhcp_server_rapid_commit);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to %s Rapid Commit support for DHCPv4 server instance: %m",
+ enable_disable(link->network->dhcp_server_rapid_commit));
+
for (sd_dhcp_lease_server_type_t type = 0; type < _SD_DHCP_LEASE_SERVER_TYPE_MAX; type ++) {
if (!link->network->dhcp_server_emit[type].emit)
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 080f72dc2c..628b1ad19f 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -342,6 +342,7 @@ DHCPServer.BindToInterface, config_parse_bool,
DHCPServer.BootServerAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_boot_server_address)
DHCPServer.BootServerName, config_parse_dns_name, 0, offsetof(Network, dhcp_server_boot_server_name)
DHCPServer.BootFilename, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, dhcp_server_boot_filename)
+DHCPServer.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp_server_rapid_commit)
DHCPServerStaticLease.Address, config_parse_dhcp_static_lease_address, 0, 0
DHCPServerStaticLease.MACAddress, config_parse_dhcp_static_lease_hwaddr, 0, 0
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index fbda52f8f3..72ed2abd95 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -428,6 +428,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_server_emit[SD_DHCP_LEASE_SIP].emit = true,
.dhcp_server_emit_router = true,
.dhcp_server_emit_timezone = true,
+ .dhcp_server_rapid_commit = true,
.router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC,
.router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 021e7f9182..4995e55b53 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -228,6 +228,7 @@ struct Network {
char *dhcp_server_boot_server_name;
char *dhcp_server_boot_filename;
usec_t dhcp_server_ipv6_only_preferred_usec;
+ bool dhcp_server_rapid_commit;
/* link-local addressing support */
AddressFamily link_local;
diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h
index 1256076b83..feafa5d1fc 100644
--- a/src/systemd/sd-dhcp-server.h
+++ b/src/systemd/sd-dhcp-server.h
@@ -85,6 +85,7 @@ int sd_dhcp_server_set_static_lease(sd_dhcp_server *server, const struct in_addr
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint64_t t);
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint64_t t);
int sd_dhcp_server_set_ipv6_only_preferred_usec(sd_dhcp_server *server, uint64_t t);
+int sd_dhcp_server_set_rapid_commit(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);