From: Ronan Pigott Date: Thu, 29 Jun 2023 23:33:57 +0000 (-0700) Subject: network: Introduce UseCaptivePortal DHCPv6 option X-Git-Tag: v254-rc1~51^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a75feb554b9b3278744f3594475cd1d3c93f111b;p=thirdparty%2Fsystemd.git network: Introduce UseCaptivePortal DHCPv6 option Acepts a boolean. When enabled requests and retains captive portal configuration from the DHCPv6 server. --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 452d2835b00..b623a4aa75b 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2290,6 +2290,14 @@ allow my_server_t localnet_peer_t:peer recv; + + UseCaptivePortal= + + When true (the default), the captive portal advertised by the DHCPv6 server will be recorded + and made available to client programs and displayed in the networkctl status output per-link. + + + UseDelegatedPrefix= diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 43be9883776..57272e7bf60 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -635,6 +635,12 @@ static int dhcp6_configure(Link *link) { return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request domains: %m"); } + if (link->network->dhcp6_use_captive_portal > 0) { + r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CAPTIVE_PORTAL); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request captive portal: %m"); + } + if (link->network->dhcp6_use_ntp) { r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 92ea9eaeefc..ab0d252b940 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -258,6 +258,7 @@ DHCPv6.UseDNS, config_parse_dhcp_use_dns, DHCPv6.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp6_use_hostname) DHCPv6.UseDomains, config_parse_dhcp_use_domains, AF_INET6, 0 DHCPv6.UseNTP, config_parse_dhcp_use_ntp, AF_INET6, 0 +DHCPv6.UseCaptivePortal, config_parse_bool, 0, offsetof(Network, dhcp6_use_captive_portal) DHCPv6.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp6_mudurl) DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0 DHCPv6.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET6, offsetof(Network, dhcp6_user_class) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index b2a2d8052c3..a92c229d4f2 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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_captive_portal = true, .dhcp6_use_rapid_commit = true, .dhcp6_duid.type = _DUID_TYPE_INVALID, .dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index b4666f1d63c..e473a725005 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -170,6 +170,7 @@ struct Network { bool dhcp6_use_hostname; bool dhcp6_use_ntp; bool dhcp6_use_ntp_set; + bool dhcp6_use_captive_portal; bool dhcp6_use_rapid_commit; DHCPUseDomains dhcp6_use_domains; bool dhcp6_use_domains_set; diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index e313d9e9182..5f5cb3239d0 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -465,7 +465,7 @@ static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, D int link_save(Link *link) { const char *admin_state, *oper_state, *carrier_state, *address_state, *ipv4_address_state, *ipv6_address_state, - *dhcp_captive_portal = NULL; + *dhcp_captive_portal = NULL, *dhcp6_captive_portal = NULL; _cleanup_(unlink_and_freep) char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; int r; @@ -613,8 +613,21 @@ int link_save(Link *link) { return r; } + if (link->dhcp6_lease && link->network->dhcp6_use_captive_portal) { + r = sd_dhcp6_lease_get_captive_portal(link->dhcp6_lease, &dhcp6_captive_portal); + if (r < 0 && r != -ENODATA) + return r; + } + + if (dhcp6_captive_portal && dhcp_captive_portal && !streq(dhcp_captive_portal, dhcp6_captive_portal)) + log_link_warning(link, "DHCPv6 Captive Portal (%s) does not match DHCPv4 (%s). Ignoring DHCPv6 portal.", + dhcp6_captive_portal, dhcp_captive_portal); + + if (dhcp_captive_portal) fprintf(f, "CAPTIVE_PORTAL=%s\n", dhcp_captive_portal); + else if (dhcp6_captive_portal) + fprintf(f, "CAPTIVE_PORTAL=%s\n", dhcp6_captive_portal); /************************************************************/