1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-11 05:17:44 +03:00

Merge pull request #24074 from yuwata/network-dhcp6-rapid-commit

network: dhcp6: re-introduce RapidCommit= setting
This commit is contained in:
Yu Watanabe 2022-07-23 08:10:01 +09:00 committed by GitHub
commit c9fbe0bd10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 5 deletions

View File

@ -2147,6 +2147,19 @@ Table=1234</programlisting></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RapidCommit=</varname></term>
<listitem>
<para>Takes a boolean. The DHCPv6 client can obtain configuration parameters from a DHCPv6 server
through a rapid two-message exchange (solicit and reply). When the rapid commit option is set by
both the DHCPv6 client and the DHCPv6 server, the two-message exchange is used. Otherwise, the
four-message exchange (solicit, advertise, request, and reply) is used. The two-message exchange
provides faster client configuration. See
<ulink url="https://tools.ietf.org/html/rfc3315#section-17.2.1">RFC 3315</ulink> for details.
Defaults to true, and the two-message exchange will be used if the server support it.</para>
</listitem>
</varlistentry>
<!-- How to use the DHCP lease -->
<varlistentry>

View File

@ -71,6 +71,7 @@ struct sd_dhcp6_client {
char **vendor_class;
OrderedHashmap *extra_options;
OrderedSet *vendor_options;
bool rapid_commit;
struct sd_dhcp6_lease *lease;

View File

@ -491,6 +491,14 @@ int dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transactio
return 0;
}
int sd_dhcp6_client_set_rapid_commit(sd_dhcp6_client *client, int enable) {
assert_return(client, -EINVAL);
assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
client->rapid_commit = enable;
return 0;
}
int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
assert_return(client, -EINVAL);
@ -714,9 +722,11 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
break;
case DHCP6_STATE_SOLICITATION:
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
if (r < 0)
return r;
if (client->rapid_commit) {
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
if (r < 0)
return r;
}
r = client_append_common_options_in_managed_mode(client, &opt, &optlen,
&client->ia_na, &client->ia_pd);
@ -1160,6 +1170,10 @@ static int client_process_advertise_or_rapid_commit_reply(
if (message->type == DHCP6_MESSAGE_REPLY) {
bool rapid_commit;
if (!client->rapid_commit)
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
"Received unexpected reply message, even we sent a solicit message without the rapid commit option, ignoring.");
r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit);
if (r < 0)
return r;
@ -1467,6 +1481,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
.ifindex = -1,
.request_ia = DHCP6_REQUEST_IA_NA | DHCP6_REQUEST_IA_PD,
.fd = -1,
.rapid_commit = true,
};
*ret = TAKE_PTR(client);

View File

@ -695,6 +695,12 @@ static int dhcp6_configure(Link *link) {
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set prefix delegation hint: %m");
}
r = sd_dhcp6_client_set_rapid_commit(client, link->network->dhcp6_use_rapid_commit);
if (r < 0)
return log_link_debug_errno(link, r,
"DHCPv6 CLIENT: Failed to %s rapid commit: %m",
enable_disable(link->network->dhcp6_use_rapid_commit));
link->dhcp6_client = TAKE_PTR(client);
return 0;

View File

@ -262,6 +262,7 @@ DHCPv6.SendOption, config_parse_dhcp_send_option,
DHCPv6.IAID, config_parse_iaid, AF_INET6, 0
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid)
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_use_rapid_commit)
IPv6AcceptRA.UseGateway, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_gateway)
IPv6AcceptRA.UseRoutePrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_route_prefix)
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
@ -555,12 +556,11 @@ DHCP.RouteMetric, config_parse_dhcp_or_ra_route_metri
DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_use_rapid_commit)
DHCP.ForceDHCPv6PDOtherInformation, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCPv4.UseDomainName, config_parse_dhcp_use_domains, AF_INET, 0
DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
DHCPv6.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0
DHCPv6.RapidCommit, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_warn_compat, DISABLED_LEGACY, 0
DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp_pd_subnet_id, 0, offsetof(Network, dhcp_pd_subnet_id)
DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp_pd_announce)

View File

@ -414,6 +414,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_use_dns = true,
.dhcp6_use_hostname = true,
.dhcp6_use_ntp = true,
.dhcp6_use_rapid_commit = true,
.dhcp6_duid.type = _DUID_TYPE_INVALID,
.dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,

View File

@ -164,6 +164,7 @@ struct Network {
bool dhcp6_use_hostname;
bool dhcp6_use_ntp;
bool dhcp6_use_ntp_set;
bool dhcp6_use_rapid_commit;
DHCPUseDomains dhcp6_use_domains;
bool dhcp6_use_domains_set;
uint32_t dhcp6_iaid;

View File

@ -262,6 +262,7 @@ int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client,
int request);
int sd_dhcp6_client_add_vendor_option(sd_dhcp6_client *client,
sd_dhcp6_option *v);
int sd_dhcp6_client_set_rapid_commit(sd_dhcp6_client *client, int enable);
int sd_dhcp6_client_get_lease(
sd_dhcp6_client *client,

View File

@ -4165,6 +4165,44 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, 'token :: dev veth99')
print('## dnsmasq log')
output = read_dnsmasq_log_file()
print(output)
self.assertIn('DHCPSOLICIT(veth-peer)', output)
self.assertNotIn('DHCPADVERTISE(veth-peer)', output)
self.assertNotIn('DHCPREQUEST(veth-peer)', output)
self.assertIn('DHCPREPLY(veth-peer)', output)
self.assertIn('sent size: 0 option: 14 rapid-commit', output)
with open(os.path.join(network_unit_dir, '25-dhcp-client-ipv6-only.network'), mode='a', encoding='utf-8') as f:
f.write('\n[DHCPv6]\nRapidCommit=no\n')
stop_dnsmasq()
start_dnsmasq()
networkctl_reload()
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# checking address
output = check_output('ip address show dev veth99 scope global')
print(output)
self.assertRegex(output, r'inet6 2600::[0-9a-f:]*/128 scope global dynamic noprefixroute')
self.assertNotIn('192.168.5', output)
# checking semi-static route
output = check_output('ip -6 route list dev veth99 2001:1234:5:9fff:ff:ff:ff:ff')
print(output)
self.assertRegex(output, 'via fe80::1034:56ff:fe78:9abd')
print('## dnsmasq log')
output = read_dnsmasq_log_file()
print(output)
self.assertIn('DHCPSOLICIT(veth-peer)', output)
self.assertIn('DHCPADVERTISE(veth-peer)', output)
self.assertIn('DHCPREQUEST(veth-peer)', output)
self.assertIn('DHCPREPLY(veth-peer)', output)
self.assertNotIn('rapid-commit', output)
def test_dhcp_client_ipv4_only(self):
copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv4-only.network')