resolve: several follow-ups for json output (#39605)

Follow-ups for #38960.
This commit is contained in:
Yu Watanabe
2025-11-10 22:32:28 +09:00
committed by GitHub
9 changed files with 110 additions and 97 deletions

View File

@@ -102,11 +102,27 @@ typedef enum StatusMode {
STATUS_DEFAULT_ROUTE,
STATUS_LLMNR,
STATUS_MDNS,
STATUS_PRIVATE,
STATUS_DNS_OVER_TLS,
STATUS_DNSSEC,
STATUS_NTA,
_STATUS_MAX,
_STATUS_INVALID = -EINVAL,
} StatusMode;
static const char* const status_mode_json_field_table[_STATUS_MAX] = {
[STATUS_ALL] = NULL,
[STATUS_DNS] = "servers",
[STATUS_DOMAIN] = "searchDomains",
[STATUS_DEFAULT_ROUTE] = "defaultRoute",
[STATUS_LLMNR] = "llmnr",
[STATUS_MDNS] = "mDNS",
[STATUS_DNS_OVER_TLS] = "dnsOverTLS",
[STATUS_DNSSEC] = "dnssec",
[STATUS_NTA] = "negativeTrustAnchors",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(status_mode_json_field, StatusMode);
typedef struct InterfaceInfo {
int index;
const char *name;
@@ -1793,41 +1809,6 @@ static char** global_protocol_status(const GlobalInfo *info) {
return TAKE_PTR(s);
}
static const char* status_mode_to_json_field(StatusMode mode) {
switch (mode) {
case STATUS_ALL:
return NULL;
case STATUS_DNS:
return "servers";
case STATUS_DOMAIN:
return "searchDomains";
case STATUS_DEFAULT_ROUTE:
return "defaultRoute";
case STATUS_LLMNR:
return "llmnr";
case STATUS_MDNS:
return "mDNS";
case STATUS_PRIVATE:
return "dnsOverTLS";
case STATUS_DNSSEC:
return "dnssec";
case STATUS_NTA:
return "negativeTrustAnchors";
default:
assert_not_reached();
}
}
static int status_json_filter_fields(sd_json_variant **configuration, StatusMode mode) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
sd_json_variant *w;
@@ -1836,7 +1817,7 @@ static int status_json_filter_fields(sd_json_variant **configuration, StatusMode
assert(configuration);
field = status_mode_to_json_field(mode);
field = status_mode_json_field_to_string(mode);
if (!field)
/* Nothing to filter for this mode. */
return 0;
@@ -1869,7 +1850,6 @@ static int status_json_filter_links(sd_json_variant **configuration, char **link
if (links)
STRV_FOREACH(ifname, links) {
int ifindex = rtnl_resolve_interface_or_warn(/* rtnl= */ NULL, *ifname);
if (ifindex < 0)
return ifindex;
@@ -2037,7 +2017,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
return 0;
case STATUS_PRIVATE:
case STATUS_DNS_OVER_TLS:
printf("%sLink %i (%s)%s: %s\n",
ansi_highlight(), ifindex, name, ansi_normal(),
strna(link_info.dns_over_tls));
@@ -2265,7 +2245,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
return 0;
case STATUS_PRIVATE:
case STATUS_DNS_OVER_TLS:
printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
strna(global_info.dns_over_tls));
@@ -3010,10 +2990,10 @@ static int verb_dns_over_tls(int argc, char **argv, void *userdata) {
}
if (arg_ifindex <= 0)
return status_all(bus, STATUS_PRIVATE);
return status_all(bus, STATUS_DNS_OVER_TLS);
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_PRIVATE, NULL);
return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNS_OVER_TLS, NULL);
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);

View File

@@ -1793,16 +1793,18 @@ bool dns_scope_is_default_route(DnsScope *scope) {
return true;
}
int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret) {
int dns_scope_to_json(DnsScope *scope, bool with_cache, sd_json_variant **ret) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *cache = NULL;
int r;
assert(scope);
assert(ret);
r = dns_cache_dump_to_json(&scope->cache, &cache);
if (r < 0)
return r;
if (with_cache) {
r = dns_cache_dump_to_json(&scope->cache, &cache);
if (r < 0)
return r;
}
return sd_json_buildo(
ret,
@@ -1810,7 +1812,7 @@ int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret) {
SD_JSON_BUILD_PAIR_CONDITION(scope->family != AF_UNSPEC, "family", SD_JSON_BUILD_INTEGER(scope->family)),
SD_JSON_BUILD_PAIR_CONDITION(!!scope->link, "ifindex", SD_JSON_BUILD_INTEGER(dns_scope_ifindex(scope))),
SD_JSON_BUILD_PAIR_CONDITION(!!scope->link, "ifname", SD_JSON_BUILD_STRING(dns_scope_ifname(scope))),
SD_JSON_BUILD_PAIR_VARIANT("cache", cache),
SD_JSON_BUILD_PAIR_CONDITION(with_cache, "cache", SD_JSON_BUILD_VARIANT(cache)),
SD_JSON_BUILD_PAIR_CONDITION(scope->protocol == DNS_PROTOCOL_DNS,
"dnssec",
SD_JSON_BUILD_STRING(dnssec_mode_to_string(scope->dnssec_mode))),

View File

@@ -120,7 +120,7 @@ int dns_scope_remove_dnssd_registered_services(DnsScope *scope);
bool dns_scope_is_default_route(DnsScope *scope);
int dns_scope_dump_cache_to_json(DnsScope *scope, sd_json_variant **ret);
int dns_scope_to_json(DnsScope *scope, bool with_cache, sd_json_variant **ret);
int dns_type_suitable_for_protocol(uint16_t type, DnsProtocol protocol);
int dns_question_types_suitable_for_protocol(DnsQuestion *q, DnsProtocol protocol);

View File

@@ -2068,39 +2068,10 @@ static int dns_configuration_json_append(
assert(configuration);
if (dns_servers) {
r = sd_json_variant_new_array(&dns_servers_json, NULL, 0);
if (r < 0)
return r;
}
if (search_domains) {
r = sd_json_variant_new_array(&search_domains_json, NULL, 0);
if (r < 0)
return r;
}
if (current_dns_server) {
r = dns_server_dump_configuration_to_json(current_dns_server, &current_dns_server_json);
if (r < 0)
return r;
}
if (fallback_dns_servers) {
r = sd_json_variant_new_array(&fallback_dns_servers_json, NULL, 0);
if (r < 0)
return r;
}
SET_FOREACH(scope, dns_scopes) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = dns_scope_dump_cache_to_json(scope, &v);
if (r < 0)
return r;
/* The cache is not relevant to the configuration of the scope. */
r = sd_json_variant_filter(&v, STRV_MAKE("cache"));
r = dns_scope_to_json(scope, /* with_cache= */ false, &v);
if (r < 0)
return r;
@@ -2112,8 +2083,6 @@ static int dns_configuration_json_append(
LIST_FOREACH(servers, s, dns_servers) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
assert(dns_servers_json);
r = dns_server_dump_configuration_to_json(s, &v);
if (r < 0)
return r;
@@ -2126,8 +2095,6 @@ static int dns_configuration_json_append(
LIST_FOREACH(domains, d, search_domains) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
assert(search_domains_json);
r = dns_search_domain_dump_to_json(d, &v);
if (r < 0)
return r;
@@ -2140,8 +2107,6 @@ static int dns_configuration_json_append(
LIST_FOREACH(servers, s, fallback_dns_servers) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
assert(fallback_dns_servers_json);
r = dns_server_dump_configuration_to_json(s, &v);
if (r < 0)
return r;
@@ -2156,9 +2121,7 @@ static int dns_configuration_json_append(
JSON_BUILD_PAIR_STRING_NON_EMPTY("ifname", ifname),
SD_JSON_BUILD_PAIR_CONDITION(ifindex > 0, "ifindex", SD_JSON_BUILD_UNSIGNED(ifindex)),
JSON_BUILD_PAIR_STRING_NON_EMPTY("delegate", delegate),
JSON_BUILD_PAIR_CONDITION_BOOLEAN(ifindex > 0 || !!delegate,
"defaultRoute",
default_route > 0),
JSON_BUILD_PAIR_TRISTATE_NON_NULL("defaultRoute", default_route),
JSON_BUILD_PAIR_VARIANT_NON_NULL("currentServer", current_dns_server_json),
JSON_BUILD_PAIR_VARIANT_NON_NULL("servers", dns_servers_json),
JSON_BUILD_PAIR_VARIANT_NON_NULL("fallbackServers", fallback_dns_servers_json),
@@ -2189,7 +2152,7 @@ static int global_dns_configuration_json_append(Manager *m, sd_json_variant **co
/* ifname = */ NULL,
/* ifindex = */ 0,
/* delegate = */ NULL,
/* default_route = */ 0,
/* default_route = */ -1,
manager_get_dns_server(m),
m->dns_servers,
m->fallback_dns_servers,
@@ -2275,7 +2238,7 @@ static int delegate_dns_configuration_json_append(DnsDelegate *d, sd_json_varian
/* ifname = */ NULL,
/* ifindex = */ 0,
d->id,
d->default_route,
d->default_route > 0, /* Defaults to false. See dns_scope_is_default_route(). */
dns_delegate_get_dns_server(d),
d->dns_servers,
/* fallback_dns_servers = */ NULL,

View File

@@ -1270,7 +1270,7 @@ static int vl_method_dump_cache(sd_varlink *link, sd_json_variant *parameters, s
LIST_FOREACH(scopes, s, m->dns_scopes) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
r = dns_scope_dump_cache_to_json(s, &j);
r = dns_scope_to_json(s, /* with_cache= */ true, &j);
if (r < 0)
return r;

View File

@@ -5,6 +5,10 @@
/* We want to reuse several structures from the io.systemd.Resolve interface, namely:
*
* - DNSProtocol
* - DNSOverTLSMode
* - ResolveSupport
* - ResolvConfMode
* - ResourceKey
* - ResourceRecord
* - DNSServer
@@ -52,13 +56,13 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ScopeCache,
SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_STRING, 0),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(protocol, DNSProtocol, 0),
SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(cache, CacheEntry, SD_VARLINK_ARRAY),
SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD(
DumpCache,
@@ -137,6 +141,10 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_method_DumpServerState,
&vl_method_DumpStatistics,
&vl_method_ResetStatistics,
&vl_type_DNSProtocol,
&vl_type_DNSOverTLSMode,
&vl_type_ResolveSupport,
&vl_type_ResolvConfMode,
&vl_type_ResourceKey,
&vl_type_ResourceRecord,
&vl_type_ResourceRecordArray,

View File

@@ -1,7 +1,48 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "resolve-util.h"
#include "varlink-io.systemd.Resolve.h"
SD_VARLINK_DEFINE_ENUM_TYPE(
DNSProtocol,
SD_VARLINK_FIELD_COMMENT("DNS"),
SD_VARLINK_DEFINE_ENUM_VALUE(dns),
SD_VARLINK_FIELD_COMMENT("Multicast DNS"),
SD_VARLINK_DEFINE_ENUM_VALUE(mdns),
SD_VARLINK_FIELD_COMMENT("LLMNR"),
SD_VARLINK_DEFINE_ENUM_VALUE(llmnr));
SD_VARLINK_DEFINE_ENUM_TYPE(
DNSOverTLSMode,
SD_VARLINK_FIELD_COMMENT("DNSOverTLS is disabled."),
SD_VARLINK_DEFINE_ENUM_VALUE(no),
SD_VARLINK_FIELD_COMMENT("DNSOverTLS is enabled."),
SD_VARLINK_DEFINE_ENUM_VALUE(yes),
SD_VARLINK_FIELD_COMMENT("Try to use DNSOverTLS, but disabled when the server does not support it."),
SD_VARLINK_DEFINE_ENUM_VALUE(opportunistic));
SD_VARLINK_DEFINE_ENUM_TYPE(
ResolveSupport,
SD_VARLINK_FIELD_COMMENT("The protocol is disabled."),
SD_VARLINK_DEFINE_ENUM_VALUE(no),
SD_VARLINK_FIELD_COMMENT("The protocol is enabled."),
SD_VARLINK_DEFINE_ENUM_VALUE(yes),
SD_VARLINK_FIELD_COMMENT("The protocol is used only for resolving."),
SD_VARLINK_DEFINE_ENUM_VALUE(resolve));
SD_VARLINK_DEFINE_ENUM_TYPE(
ResolvConfMode,
SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_UPLINK_RESOLV_CONF"."),
SD_VARLINK_DEFINE_ENUM_VALUE(uplink),
SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_STUB_RESOLV_CONF"."),
SD_VARLINK_DEFINE_ENUM_VALUE(stub),
SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is a symbolic link to "PRIVATE_STATIC_RESOLV_CONF"."),
SD_VARLINK_DEFINE_ENUM_VALUE(static),
SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf does not exist."),
SD_VARLINK_DEFINE_ENUM_VALUE(missing),
SD_VARLINK_FIELD_COMMENT("/etc/resolv.conf is not managed by systemd-resolved."),
SD_VARLINK_DEFINE_ENUM_VALUE(foreign));
SD_VARLINK_DEFINE_STRUCT_TYPE(
ResourceKey,
SD_VARLINK_FIELD_COMMENT("The RR class, almost always IN, i.e 0x01. If unspecified defaults to IN."),
@@ -199,7 +240,7 @@ SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_DEFINE_STRUCT_TYPE(
DNSScope,
SD_VARLINK_FIELD_COMMENT("Protocol associated with this scope."),
SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_STRING, 0),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(protocol, DNSProtocol, 0),
SD_VARLINK_FIELD_COMMENT("Address family associated with this scope."),
SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Interface index associated with this scope."),
@@ -209,7 +250,7 @@ SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_FIELD_COMMENT("DNSSEC mode associated with this scope."),
SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("DNSOverTLS mode associated with this scope."),
SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE));
SD_VARLINK_DEFINE_STRUCT_TYPE(
DNSConfiguration,
@@ -234,13 +275,14 @@ SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_FIELD_COMMENT("DNSSEC mode."),
SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("DNSOverTLS mode."),
SD_VARLINK_DEFINE_FIELD(dnsOverTLS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("LLMNR support."),
//SD_VARLINK_DEFINE_FIELD_BY_TYPE(llmnr, ResolveSupport, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD(llmnr, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("mDNS support."),
SD_VARLINK_DEFINE_FIELD(mDNS, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(mDNS, ResolveSupport, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("resolv.conf mode, set for global configuration only."),
SD_VARLINK_DEFINE_FIELD(resolvConfMode, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(resolvConfMode, ResolvConfMode, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Array of current DNS scopes."),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(scopes, DNSScope, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
@@ -317,6 +359,14 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_method_BrowseServices,
SD_VARLINK_SYMBOL_COMMENT("Current global and per-link DNS configurations."),
&vl_method_DumpDNSConfiguration,
SD_VARLINK_SYMBOL_COMMENT("The type of protocol."),
&vl_type_DNSProtocol,
SD_VARLINK_SYMBOL_COMMENT("The mode of DNSOverTLS."),
&vl_type_DNSOverTLSMode,
SD_VARLINK_SYMBOL_COMMENT("Whether the protocol is enabled."),
&vl_type_ResolveSupport,
SD_VARLINK_SYMBOL_COMMENT("The management mode of /etc/resolve.conf file."),
&vl_type_ResolvConfMode,
SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved address."),
&vl_type_ResolvedAddress,
SD_VARLINK_SYMBOL_COMMENT("Encapsulates a resolved host name."),

View File

@@ -3,6 +3,10 @@
#include "sd-varlink-idl.h"
extern const sd_varlink_symbol vl_type_DNSProtocol;
extern const sd_varlink_symbol vl_type_DNSOverTLSMode;
extern const sd_varlink_symbol vl_type_ResolveSupport;
extern const sd_varlink_symbol vl_type_ResolvConfMode;
extern const sd_varlink_symbol vl_type_ResourceKey;
extern const sd_varlink_symbol vl_type_ResourceRecord;
extern const sd_varlink_symbol vl_type_DNSServer;

View File

@@ -13,6 +13,7 @@
#include "json-util.h"
#include "network-util.h"
#include "pretty-print.h"
#include "resolve-util.h"
#include "tests.h"
#include "varlink-idl-util.h"
#include "varlink-io.systemd.h"
@@ -512,13 +513,18 @@ static void test_enum_to_string_name(const char *n, const sd_varlink_symbol *sym
TEST(enums_idl) {
TEST_IDL_ENUM(BootEntryType, boot_entry_type, vl_type_BootEntryType);
TEST_IDL_ENUM_TO_STRING(BootEntrySource, boot_entry_source, vl_type_BootEntrySource);
TEST_IDL_ENUM(PartitionDesignator, partition_designator, vl_type_PartitionDesignator);
TEST_IDL_ENUM(LinkAddressState, link_address_state, vl_type_LinkAddressState);
TEST_IDL_ENUM_TO_STRING(LinkAddressState, link_address_state, vl_type_LinkAddressState);
TEST_IDL_ENUM(LinkOnlineState, link_online_state, vl_type_LinkOnlineState);
TEST_IDL_ENUM_TO_STRING(LinkOnlineState, link_online_state, vl_type_LinkOnlineState);
TEST_IDL_ENUM(AddressFamily, link_required_address_family, vl_type_LinkRequiredAddressFamily);
TEST_IDL_ENUM_TO_STRING(AddressFamily, link_required_address_family, vl_type_LinkRequiredAddressFamily);
TEST_IDL_ENUM(DnsOverTlsMode, dns_over_tls_mode, vl_type_DNSOverTLSMode);
TEST_IDL_ENUM(ResolveSupport, resolve_support, vl_type_ResolveSupport);
}
DEFINE_TEST_MAIN(LOG_DEBUG);