summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-dhcp4.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-09-20 07:29:06 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-10-11 14:42:13 +0200
commitfc35a9f8d1632c4e7a279228f869bfc77d8f5b9c (patch)
treebb68dbc95f9639bc6079e0c815312d8cedb422a6 /src/network/networkd-dhcp4.c
parentsd-dhcp-client: support IPv6 only mode (diff)
downloadsystemd-fc35a9f8d1632c4e7a279228f869bfc77d8f5b9c.tar.xz
systemd-fc35a9f8d1632c4e7a279228f869bfc77d8f5b9c.zip
network/dhcp4: support IPv6 only mode (RFC 8925)
Co-authored-by: Susant Sahani <ssahani@gmail.com>
Diffstat (limited to 'src/network/networkd-dhcp4.c')
-rw-r--r--src/network/networkd-dhcp4.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 3e8038ede6..57d40e856e 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1452,6 +1452,16 @@ static bool link_needs_dhcp_broadcast(Link *link) {
return r == true;
}
+static bool link_dhcp4_ipv6_only_mode(Link *link) {
+ assert(link);
+ assert(link->network);
+
+ if (link->network->dhcp_ipv6_only_mode >= 0)
+ return link->network->dhcp_ipv6_only_mode;
+
+ return link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link);
+}
+
static int dhcp4_configure(Link *link) {
sd_dhcp_option *send_option;
void *request_options;
@@ -1560,6 +1570,12 @@ static int dhcp4_configure(Link *link) {
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for 6rd: %m");
}
+ if (link_dhcp4_ipv6_only_mode(link)) {
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_IPV6_ONLY_PREFERRED);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for IPv6-only preferred option: %m");
+ }
+
SET_FOREACH(request_options, link->network->dhcp_request_options) {
uint32_t option = PTR_TO_UINT32(request_options);
@@ -1668,7 +1684,7 @@ int dhcp4_update_mac(Link *link) {
return r;
if (restart) {
- r = sd_dhcp_client_start(link->dhcp_client);
+ r = dhcp4_start(link);
if (r < 0)
return r;
}
@@ -1676,10 +1692,35 @@ int dhcp4_update_mac(Link *link) {
return 0;
}
-int dhcp4_start(Link *link) {
+int dhcp4_update_ipv6_connectivity(Link *link) {
+ assert(link);
+
+ if (!link->network)
+ return 0;
+
+ if (!link->network->dhcp_ipv6_only_mode)
+ return 0;
+
+ if (!link->dhcp_client)
+ return 0;
+
+ /* If the client is running, set the current connectivity. */
+ if (sd_dhcp_client_is_running(link->dhcp_client))
+ return sd_dhcp_client_set_ipv6_connectivity(link->dhcp_client, link_has_ipv6_connectivity(link));
+
+ /* If the client has been already stopped or not started yet, let's check the current connectivity
+ * and start the client if necessary. */
+ if (link_has_ipv6_connectivity(link))
+ return 0;
+
+ return dhcp4_start_full(link, /* set_ipv6_connectivity = */ false);
+}
+
+int dhcp4_start_full(Link *link, bool set_ipv6_connectivity) {
int r;
assert(link);
+ assert(link->network);
if (!link->dhcp_client)
return 0;
@@ -1694,6 +1735,12 @@ int dhcp4_start(Link *link) {
if (r < 0)
return r;
+ if (set_ipv6_connectivity) {
+ r = dhcp4_update_ipv6_connectivity(link);
+ if (r < 0)
+ return r;
+ }
+
return 1;
}