]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/dhcp6: add SIP server support
authorhaxibami <me@haxibami.net>
Tue, 22 Jul 2025 08:05:13 +0000 (17:05 +0900)
committerhaxibami <me@haxibami.net>
Tue, 22 Jul 2025 08:05:13 +0000 (17:05 +0900)
man/systemd.network.xml
src/network/networkd-dhcp6.c
src/network/networkd-json.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-state-file.c

index 1b4d303fc83b32a4f03cb128a133f2a34ffabb25..f1becd46274ada2805b013acf91f601dcec5c99e 100644 (file)
@@ -3233,6 +3233,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
         <term><varname>UseDNS=</varname></term>
         <term><varname>UseDNR=</varname></term>
         <term><varname>UseNTP=</varname></term>
+        <term><varname>UseSIP=</varname></term>
         <term><varname>UseHostname=</varname></term>
         <term><varname>UseDomains=</varname></term>
         <term><varname>NetLabel=</varname></term>
index 6570e13d660d21e70697136254330af755d4f324..cae497278fbb4fef639204c4958ec17ac05b6df9 100644 (file)
@@ -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);
 
index b6b4b02c06fb1075b22e1629a9546f76f1ef5307..aa65379acc8e2197fbfecd6c726f5dffe193c7d5 100644 (file)
@@ -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) {
index 577dccc9eb020d30933d8884613f00885191b6d1..52fc0ab44427f3f546b4a3c7c0940e1ee664d15b 100644 (file)
@@ -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
index 961b431a68e66e3bbfae14ceea3c9075b9b7e6db..e27fabea81a89fc2b06d4fd4455e372094f7cdee 100644 (file)
@@ -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,
index 0e14cfa7b5b51e87acea4f2820add111a0a9ab8c..677d337e0f219d5405d035b39df5f4c7360e4f15 100644 (file)
@@ -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;
index abd8b5a4ef60c739f22afd19c5dd4b057a4355cd..21bf4b1b3450bb7db88d59d894258087450d85e6 100644 (file)
@@ -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);
 
                 /************************************************************/