]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: add dnr resolvers to networkctl status json output
authorRonan Pigott <ronan@rjp.ie>
Wed, 3 Apr 2024 20:16:05 +0000 (13:16 -0700)
committerRonan Pigott <ronan@rjp.ie>
Mon, 21 Oct 2024 16:10:20 +0000 (09:10 -0700)
src/libsystemd-network/sd-dhcp6-lease.c
src/network/networkd-json.c
src/shared/dns-resolver-internal.h
src/shared/sd-dns-resolver.c

index 22707b771d57b4eafaabba185bcffeef705aab19..2729984e308c2fa519056bba95f829ec5bdd1eb9 100644 (file)
@@ -491,7 +491,7 @@ static int dhcp6_lease_add_dnr(sd_dhcp6_lease *lease, const uint8_t *optval, siz
 
         res.addrs = new(union in_addr_union, n_addrs);
         if (!res.addrs)
-                return -ENOMEM
+                return -ENOMEM;
 
         for (size_t i = 0; i < n_addrs; i++) {
                 union in_addr_union addr = {.in6 = addrs[i]};
index 4eafc62c7e481cbead0a97308d5670d2dc69e296..24f3378d57528fdab0af48b4487a9c1f83f19efa 100644 (file)
@@ -503,6 +503,117 @@ static int dns_append_json(Link *link, sd_json_variant **v) {
         return json_variant_set_field_non_null(v, "DNS", array);
 }
 
+static int dnr_append_json_one(Link *link, const struct sd_dns_resolver *res, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *addrs_array = NULL;
+        _cleanup_strv_free_ char **transports = NULL;
+        int r;
+
+        assert(link);
+        assert(res);
+        assert(array);
+
+        FOREACH_ARRAY(addr, res->addrs, res->n_addrs) {
+                r = sd_json_variant_append_arrayb(
+                                &addrs_array,
+                                JSON_BUILD_IN_ADDR(addr, res->family));
+                if (r < 0)
+                        return r;
+        }
+
+        r = dns_resolver_transports_to_strv(res->transports, &transports);
+        if (r < 0)
+                return r;
+
+        //FIXME ifindex?
+        return sd_json_variant_append_arrayb(
+                        array,
+                        SD_JSON_BUILD_OBJECT(
+                                        SD_JSON_BUILD_PAIR_INTEGER("Family", res->family),
+                                        SD_JSON_BUILD_PAIR_INTEGER("Priority", res->priority),
+                                        JSON_BUILD_PAIR_VARIANT_NON_NULL("Addresses", addrs_array),
+                                        JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("Port", res->port),
+                                        JSON_BUILD_PAIR_STRING_NON_EMPTY("ServerName", res->auth_name),
+                                        JSON_BUILD_PAIR_STRING_NON_EMPTY("DoHPath", res->dohpath),
+                                        JSON_BUILD_PAIR_STRV_NON_EMPTY("Transports", transports),
+                                        SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)),
+                                        JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, res->family)));
+}
+
+static int dnr_append_json(Link *link, sd_json_variant **v) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
+        int r;
+
+        assert(link);
+        assert(v);
+
+        if (!link->network)
+                return 0;
+
+        if (link->dhcp_lease && link_get_use_dnr(link, NETWORK_CONFIG_SOURCE_DHCP4)) {
+                struct sd_dns_resolver *dnr;
+                union in_addr_union s;
+                int n_dnr;
+
+                r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
+                if (r < 0)
+                        return r;
+
+                n_dnr = sd_dhcp_lease_get_dnr(link->dhcp_lease, &dnr);
+                if (n_dnr < 0)
+                        return 0;
+
+                FOREACH_ARRAY(res, dnr, n_dnr) {
+                        r = dnr_append_json_one(link,
+                                                res,
+                                                NETWORK_CONFIG_SOURCE_DHCP4,
+                                                &s,
+                                                &array);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        if (link->dhcp6_lease && link_get_use_dnr(link, NETWORK_CONFIG_SOURCE_DHCP6)) {
+                struct sd_dns_resolver *dnr;
+                union in_addr_union s;
+                int n_dnr;
+
+                r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
+                if (r < 0)
+                        return r;
+
+                n_dnr = sd_dhcp6_lease_get_dnr(link->dhcp6_lease, &dnr);
+                if (n_dnr < 0)
+                        return 0;
+
+                FOREACH_ARRAY(res, dnr, n_dnr) {
+                        r = dnr_append_json_one(link,
+                                                res,
+                                                NETWORK_CONFIG_SOURCE_DHCP6,
+                                                &s,
+                                                &array);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        if (link_get_use_dnr(link, NETWORK_CONFIG_SOURCE_NDISC)) {
+                NDiscDNR *a;
+
+                SET_FOREACH(a, link->ndisc_dnr) {
+                        r = dnr_append_json_one(link,
+                                                &a->resolver,
+                                                NETWORK_CONFIG_SOURCE_NDISC,
+                                                &(union in_addr_union) { .in6 = a->router },
+                                                &array);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return json_variant_set_field_non_null(v, "DNR", array);
+}
+
 static int server_append_json_one_addr(int family, const union in_addr_union *a, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) {
         assert(IN_SET(family, AF_INET, AF_INET6));
         assert(a);
@@ -1268,6 +1379,10 @@ int link_build_json(Link *link, sd_json_variant **ret) {
         if (r < 0)
                 return r;
 
+        r = dnr_append_json(link, &v);
+        if (r < 0)
+                return r;
+
         r = ntp_append_json(link, &v);
         if (r < 0)
                 return r;
index 08ef782408a117c09f70c3bbe412ce088b824e6e..e5c185c2e072579a26822f3cf47122a7a16ec487 100644 (file)
@@ -43,6 +43,8 @@ struct sd_dns_resolver {
 
 void siphash24_compress_resolver(const sd_dns_resolver *res, struct siphash *state);
 
+int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret);
+
 int dns_resolvers_to_dot_addrs(const sd_dns_resolver *resolvers, size_t n_resolvers,
                 struct in_addr_full ***ret_addrs, size_t *ret_n_addrs);
 
index 4c76df18d1fd344c0374cee618da7c2d386ec866..548672cd33102fbc9eecb04ca00638158ea917d7 100644 (file)
@@ -174,6 +174,32 @@ const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX
         return snprintf_ok(buf, DECIMAL_STR_MAX(uint16_t)+3, "key%i", i);
 }
 
+int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret) {
+        _cleanup_strv_free_ char **ans = NULL;
+
+        assert(ret);
+
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DO53)) {
+                /* Do53 has no ALPN, this flag is only for our own usage. */
+        }
+
+        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_2_TLS))
+                if (strv_extend(&ans, "h2") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_3))
+                if (strv_extend(&ans, "h3") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DOT))
+                if (strv_extend(&ans, "dot") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DOQ))
+                if (strv_extend(&ans, "doq") < 0)
+                        return -ENOMEM;
+
+        *ret = TAKE_PTR(ans);
+        return 0;
+}
+
 int dnr_parse_svc_params(const uint8_t *option, size_t len, sd_dns_resolver *resolver) {
         size_t offset = 0;
         int r;