From: haxibami Date: Tue, 22 Jul 2025 08:05:13 +0000 (+0900) Subject: network/dhcp6: add SIP server support X-Git-Tag: v258-rc1~15^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=238c427aa9c4bc28c1840e550551a984b33d44da;p=thirdparty%2Fsystemd.git network/dhcp6: add SIP server support --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 1b4d303fc83..f1becd46274 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -3233,6 +3233,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix UseDNS= UseDNR= UseNTP= + UseSIP= UseHostname= UseDomains= NetLabel= diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 6570e13d660..cae497278fb 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -687,6 +687,16 @@ static int dhcp6_configure(Link *link) { return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SNTP servers: %m"); } + if (link->network->dhcp6_use_sip > 0) { + r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SIP servers: %m"); + + r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SIP server domain names: %m"); + } + SET_FOREACH(request_options, link->network->dhcp6_request_options) { uint32_t option = PTR_TO_UINT32(request_options); diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index b6b4b02c06f..aa65379acc8 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -819,49 +819,88 @@ static int ntp_append_json(Link *link, sd_json_variant **v) { return json_variant_set_field_non_null(v, "NTP", array); } +static int domain_append_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) { + assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); + assert(domain); + assert(array); + + return sd_json_variant_append_arraybo( + array, + SD_JSON_BUILD_PAIR_STRING("Domain", domain), + SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), + JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family)); +} + static int sip_append_json(Link *link, sd_json_variant **v) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL; - const struct in_addr *sip; - union in_addr_union s; - int n_sip, r; + int r; assert(link); assert(v); - if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease) + if (!link->network) return 0; - n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip); - if (n_sip <= 0) - return 0; + if (link->dhcp_lease && link->network->dhcp_use_sip) { + const struct in_addr *sip; + union in_addr_union s; + int n_sip; - r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); - if (r < 0) - return r; + n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip); + if (n_sip <= 0) + return 0; - for (int i = 0; i < n_sip; i++) { - r = server_append_json_one_addr(AF_INET, - &(union in_addr_union) { .in = sip[i], }, - NETWORK_CONFIG_SOURCE_DHCP4, - &s, - &array); + r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); if (r < 0) return r; + + for (int i = 0; i < n_sip; i++) { + r = server_append_json_one_addr(AF_INET, + &(union in_addr_union) { .in = sip[i], }, + NETWORK_CONFIG_SOURCE_DHCP4, + &s, + &array); + if (r < 0) + return r; + } + } - return json_variant_set_field_non_null(v, "SIP", array); -} + if (link->dhcp6_lease && link->network->dhcp6_use_sip) { + const struct in6_addr *sip_addr; + union in_addr_union s; + char **domains; + int n_sip; -static int domain_append_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) { - assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); - assert(domain); - assert(array); + r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); + if (r < 0) + return r; - return sd_json_variant_append_arraybo( - array, - SD_JSON_BUILD_PAIR_STRING("Domain", domain), - SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), - JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family)); + n_sip = sd_dhcp6_lease_get_sip_addrs(link->dhcp6_lease, &sip_addr); + for (int i = 0; i < n_sip; i++) { + r = server_append_json_one_addr(AF_INET6, + &(union in_addr_union) { .in6 = sip_addr[i], }, + NETWORK_CONFIG_SOURCE_DHCP6, + &s, + &array); + if (r < 0) + return r; + } + + if (sd_dhcp6_lease_get_sip_domains(link->dhcp6_lease, &domains) >= 0) + STRV_FOREACH(p, domains) { + r = domain_append_json(AF_INET6, + *p, + NETWORK_CONFIG_SOURCE_DHCP6, + &s, + &array); + if (r < 0) + return r; + } + + } + + return json_variant_set_field_non_null(v, "SIP", array); } static int domains_append_json(Link *link, bool is_route, sd_json_variant **v) { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 577dccc9eb0..52fc0ab4442 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -310,6 +310,7 @@ DHCPv6.UseDNR, config_parse_tristate, DHCPv6.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp6_use_hostname) DHCPv6.UseDomains, config_parse_use_domains, 0, offsetof(Network, dhcp6_use_domains) DHCPv6.UseNTP, config_parse_tristate, 0, offsetof(Network, dhcp6_use_ntp) +DHCPv6.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp6_use_sip) DHCPv6.UseCaptivePortal, config_parse_bool, 0, offsetof(Network, dhcp6_use_captive_portal) DHCPv6.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp6_mudurl) DHCPv6.SendHostname, config_parse_dhcp_send_hostname, AF_INET6, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 961b431a68e..e27fabea81a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -413,6 +413,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp6_use_domains = _USE_DOMAINS_INVALID, .dhcp6_use_hostname = true, .dhcp6_use_ntp = -1, + .dhcp6_use_sip = true, .dhcp6_use_captive_portal = true, .dhcp6_use_rapid_commit = true, .dhcp6_send_hostname = true, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 0e14cfa7b5b..677d337e0f2 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -181,6 +181,7 @@ typedef struct Network { int dhcp6_use_dnr; bool dhcp6_use_hostname; int dhcp6_use_ntp; + bool dhcp6_use_sip; bool dhcp6_use_captive_portal; bool dhcp6_use_rapid_commit; UseDomains dhcp6_use_domains; diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index abd8b5a4ef6..21bf4b1b345 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -264,6 +264,25 @@ static int link_put_sip(Link *link, OrderedSet **s) { } } + if (link->dhcp6_lease && link->network->dhcp6_use_sip) { + const struct in6_addr *addresses; + char **domains; + + r = sd_dhcp6_lease_get_sip_addrs(link->dhcp6_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in6_addrv(s, addresses, r); + if (r < 0) + return r; + } + + r = sd_dhcp6_lease_get_sip_domains(link->dhcp6_lease, &domains); + if (r >= 0) { + r = ordered_set_put_strdupv_full(s, &dns_name_hash_ops_free, domains); + if (r < 0) + return r; + } + } + return 0; } @@ -842,7 +861,10 @@ static int link_save(Link *link) { link->dhcp_lease, link->network->dhcp_use_sip, SD_DHCP_LEASE_SIP, - NULL, false, NULL, NULL); + link->dhcp6_lease, + link->network->dhcp6_use_sip, + sd_dhcp6_lease_get_sip_addrs, + sd_dhcp6_lease_get_sip_domains); /************************************************************/