diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-11-08 04:20:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-08 04:20:17 +0100 |
commit | b2622db0df5bcd82529a781ed1209f8ddeb18f8e (patch) | |
tree | 2259ba415687489c6b4cfdf909dbb90f349a8817 | |
parent | Merge pull request #29913 from keszybz/vmspawn-ci (diff) | |
parent | network: add [DHCPServer] RapidCommit= setting (diff) | |
download | systemd-b2622db0df5bcd82529a781ed1209f8ddeb18f8e.tar.xz systemd-b2622db0df5bcd82529a781ed1209f8ddeb18f8e.zip |
Merge pull request #29910 from yuwata/rapid-commit
dhcp: about rapid commit
-rw-r--r-- | man/systemd.network.xml | 12 | ||||
-rw-r--r-- | src/libsystemd-network/dhcp-server-internal.h | 2 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 5 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-server.c | 27 | ||||
-rw-r--r-- | src/network/networkd-dhcp-server.c | 5 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
-rw-r--r-- | src/network/networkd-network.c | 1 | ||||
-rw-r--r-- | src/network/networkd-network.h | 1 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-server.h | 1 |
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); |