resolvectl: re-implement normal status output using varlink (#40529)
Currently, `resolvectl status` (and other status commands like `resolvectl dns $iface`) uses varlink when asked to print JSON, but uses dbus otherwise. This PR re-implements the regular status output to use varlink instead of dbus. This both simplifies the `resolvectl status` code, and is an incremental step in replacing dbus usage with varlink throughout `resolvectl`. The first several commits move `dns-configuration.[ch]` from `src/network/wait-online` to `src/shared`, and complete the JSON dispatching so that all fields are available in a concrete type. The next few commits re-implement global, link, and delegate status output. Finally, the last commits consolidate and simplify the status logic since varlink and the `DNSConfiguration` type can be used in all cases.
This commit is contained in:
@@ -116,7 +116,6 @@ systemd_networkd_extract_sources = files(
|
||||
)
|
||||
|
||||
systemd_networkd_wait_online_sources = files(
|
||||
'wait-online/dns-configuration.c',
|
||||
'wait-online/wait-online-link.c',
|
||||
'wait-online/wait-online-manager.c',
|
||||
'wait-online/wait-online.c',
|
||||
|
||||
+443
-1065
File diff suppressed because it is too large
Load Diff
@@ -2055,6 +2055,7 @@ static int dns_configuration_json_append(
|
||||
Set *negative_trust_anchors,
|
||||
Set *dns_scopes,
|
||||
DnssecMode dnssec_mode,
|
||||
bool dnssec_supported,
|
||||
DnsOverTlsMode dns_over_tls_mode,
|
||||
ResolveSupport llmnr_support,
|
||||
ResolveSupport mdns_support,
|
||||
@@ -2138,6 +2139,7 @@ static int dns_configuration_json_append(
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!set_isempty(negative_trust_anchors),
|
||||
"negativeTrustAnchors",
|
||||
JSON_BUILD_STRING_SET(negative_trust_anchors)),
|
||||
JSON_BUILD_PAIR_CONDITION_BOOLEAN(dnssec_mode >= 0, "dnssecSupported", dnssec_supported),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("dnssec", dnssec_mode_to_string(dnssec_mode)),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("dnsOverTLS", dns_over_tls_mode_to_string(dns_over_tls_mode)),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("llmnr", resolve_support_to_string(llmnr_support)),
|
||||
@@ -2169,6 +2171,7 @@ static int global_dns_configuration_json_append(Manager *m, sd_json_variant **co
|
||||
m->trust_anchor.negative_by_name,
|
||||
scopes,
|
||||
manager_get_dnssec_mode(m),
|
||||
manager_dnssec_supported(m),
|
||||
manager_get_dns_over_tls_mode(m),
|
||||
m->llmnr_support,
|
||||
m->mdns_support,
|
||||
@@ -2225,6 +2228,7 @@ static int link_dns_configuration_json_append(Link *l, sd_json_variant **configu
|
||||
l->dnssec_negative_trust_anchors,
|
||||
scopes,
|
||||
link_get_dnssec_mode(l),
|
||||
link_dnssec_supported(l),
|
||||
link_get_dns_over_tls_mode(l),
|
||||
link_get_llmnr_support(l),
|
||||
link_get_mdns_support(l),
|
||||
@@ -2255,6 +2259,7 @@ static int delegate_dns_configuration_json_append(DnsDelegate *d, sd_json_varian
|
||||
/* negative_trust_anchors= */ NULL,
|
||||
scopes,
|
||||
/* dnssec_mode= */ _DNSSEC_MODE_INVALID,
|
||||
/* dnssec_supported= */ false,
|
||||
/* dns_over_tls_mode= */ _DNS_OVER_TLS_MODE_INVALID,
|
||||
/* llmnr_support= */ _RESOLVE_SUPPORT_INVALID,
|
||||
/* mdns_support= */ _RESOLVE_SUPPORT_INVALID,
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
#include "in-addr-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "json-util.h"
|
||||
#include "ordered-set.h"
|
||||
#include "set.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
DNSServer* dns_server_free(DNSServer *s) {
|
||||
if (!s)
|
||||
@@ -57,6 +59,7 @@ static int dispatch_dns_server(const char *name, sd_json_variant *variant, sd_js
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Dispatched address size (%zu) is incompatible with the family (%s).",
|
||||
s->addr.iov_len, af_to_ipv4_ipv6(s->family));
|
||||
memcpy_safe(&s->in_addr, s->addr.iov_base, s->addr.iov_len);
|
||||
|
||||
*ret = TAKE_PTR(s);
|
||||
|
||||
@@ -64,8 +67,8 @@ static int dispatch_dns_server(const char *name, sd_json_variant *variant, sd_js
|
||||
}
|
||||
|
||||
static int dispatch_dns_server_array(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
Set **ret = ASSERT_PTR(userdata);
|
||||
_cleanup_set_free_ Set *dns_servers = NULL;
|
||||
OrderedSet **ret = ASSERT_PTR(userdata);
|
||||
_cleanup_ordered_set_free_ OrderedSet *dns_servers = NULL;
|
||||
sd_json_variant *v;
|
||||
int r;
|
||||
|
||||
@@ -76,12 +79,13 @@ static int dispatch_dns_server_array(const char *name, sd_json_variant *variant,
|
||||
if (r < 0)
|
||||
return json_log(v, flags, r, "JSON array element is not a valid DNSServer.");
|
||||
|
||||
r = set_ensure_consume(&dns_servers, &dns_server_hash_ops, TAKE_PTR(s));
|
||||
r = ordered_set_ensure_put(&dns_servers, &dns_server_hash_ops, s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
TAKE_PTR(s);
|
||||
}
|
||||
|
||||
set_free_and_replace(*ret, dns_servers);
|
||||
free_and_replace_full(*ret, dns_servers, ordered_set_free);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -128,8 +132,8 @@ static int dispatch_search_domain(const char *name, sd_json_variant *variant, sd
|
||||
}
|
||||
|
||||
static int dispatch_search_domain_array(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
Set **ret = ASSERT_PTR(userdata);
|
||||
_cleanup_set_free_ Set *search_domains = NULL;
|
||||
OrderedSet **ret = ASSERT_PTR(userdata);
|
||||
_cleanup_ordered_set_free_ OrderedSet *search_domains = NULL;
|
||||
sd_json_variant *v;
|
||||
int r;
|
||||
|
||||
@@ -140,12 +144,82 @@ static int dispatch_search_domain_array(const char *name, sd_json_variant *varia
|
||||
if (r < 0)
|
||||
return json_log(v, flags, r, "JSON array element is not a valid SearchDomain.");
|
||||
|
||||
r = set_ensure_consume(&search_domains, &search_domain_hash_ops, TAKE_PTR(d));
|
||||
r = ordered_set_ensure_put(&search_domains, &search_domain_hash_ops, d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
TAKE_PTR(d);
|
||||
}
|
||||
|
||||
free_and_replace_full(*ret, search_domains, ordered_set_free);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DNSScope* dns_scope_free(DNSScope *s) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
free(s->ifname);
|
||||
free(s->protocol);
|
||||
free(s->dnssec_mode_str);
|
||||
free(s->dns_over_tls_mode_str);
|
||||
|
||||
return mfree(s);
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
dns_scope_hash_ops,
|
||||
void,
|
||||
trivial_hash_func,
|
||||
trivial_compare_func,
|
||||
DNSScope,
|
||||
dns_scope_free);
|
||||
|
||||
static int dispatch_dns_scope(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
static const sd_json_dispatch_field dns_scope_dispatch_table[] = {
|
||||
{ "protocol", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSScope, protocol), SD_JSON_MANDATORY },
|
||||
{ "family", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(DNSScope, family), 0 },
|
||||
{ "ifname", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSScope, ifname), 0 },
|
||||
{ "ifindex", SD_JSON_VARIANT_UNSIGNED, json_dispatch_ifindex, offsetof(DNSScope, ifindex), SD_JSON_RELAX },
|
||||
{ "dnssec", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSScope, dnssec_mode_str), 0 },
|
||||
{ "dnsOverTLS", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSScope, dns_over_tls_mode_str), 0 },
|
||||
{},
|
||||
};
|
||||
DNSScope **ret = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
_cleanup_(dns_scope_freep) DNSScope *s = new0(DNSScope, 1);
|
||||
if (!s)
|
||||
return log_oom();
|
||||
|
||||
r = sd_json_dispatch(variant, dns_scope_dispatch_table, flags, s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dispatch_dns_scope_array(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
Set **ret = ASSERT_PTR(userdata);
|
||||
_cleanup_set_free_ Set *dns_scopes = NULL;
|
||||
sd_json_variant *v;
|
||||
int r;
|
||||
|
||||
JSON_VARIANT_ARRAY_FOREACH(v, variant) {
|
||||
_cleanup_(dns_scope_freep) DNSScope *s = NULL;
|
||||
|
||||
r = dispatch_dns_scope(name, v, flags, &s);
|
||||
if (r < 0)
|
||||
return json_log(v, flags, r, "JSON array element is not a valid DNSScope.");
|
||||
|
||||
r = set_ensure_consume(&dns_scopes, &dns_scope_hash_ops, TAKE_PTR(s));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
set_free_and_replace(*ret, search_domains);
|
||||
set_free_and_replace(*ret, dns_scopes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -155,9 +229,18 @@ DNSConfiguration* dns_configuration_free(DNSConfiguration *c) {
|
||||
return NULL;
|
||||
|
||||
dns_server_free(c->current_dns_server);
|
||||
set_free(c->dns_servers);
|
||||
set_free(c->search_domains);
|
||||
ordered_set_free(c->dns_servers);
|
||||
ordered_set_free(c->search_domains);
|
||||
ordered_set_free(c->fallback_dns_servers);
|
||||
set_free(c->dns_scopes);
|
||||
free(c->ifname);
|
||||
free(c->dnssec_mode_str);
|
||||
free(c->dns_over_tls_mode_str);
|
||||
free(c->llmnr_mode_str);
|
||||
free(c->mdns_mode_str);
|
||||
free(c->resolv_conf_mode_str);
|
||||
free(c->delegate);
|
||||
strv_free(c->negative_trust_anchors);
|
||||
|
||||
return mfree(c);
|
||||
}
|
||||
@@ -172,23 +255,22 @@ DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
|
||||
static int dispatch_dns_configuration(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
static const sd_json_dispatch_field dns_configuration_dispatch_table[] = {
|
||||
{ "ifname", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, ifname), 0 },
|
||||
{ "ifindex", SD_JSON_VARIANT_UNSIGNED, json_dispatch_ifindex, offsetof(DNSConfiguration, ifindex), SD_JSON_RELAX },
|
||||
{ "defaultRoute", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DNSConfiguration, default_route), 0 },
|
||||
{ "currentServer", SD_JSON_VARIANT_OBJECT, dispatch_dns_server, offsetof(DNSConfiguration, current_dns_server), 0 },
|
||||
{ "servers", SD_JSON_VARIANT_ARRAY, dispatch_dns_server_array, offsetof(DNSConfiguration, dns_servers), 0 },
|
||||
{ "searchDomains", SD_JSON_VARIANT_ARRAY, dispatch_search_domain_array, offsetof(DNSConfiguration, search_domains), 0 },
|
||||
|
||||
/* The remaining fields are currently unused by wait-online. */
|
||||
{ "delegate", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "fallbackServers", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "negativeTrustAnchors", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "dnssec", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "dnsOverTLS", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "llmnr", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "mDNS", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "resolvConfMode", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "scopes", _SD_JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
|
||||
{ "ifname", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, ifname), 0 },
|
||||
{ "ifindex", SD_JSON_VARIANT_UNSIGNED, json_dispatch_ifindex, offsetof(DNSConfiguration, ifindex), SD_JSON_RELAX },
|
||||
{ "defaultRoute", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DNSConfiguration, default_route), 0 },
|
||||
{ "currentServer", SD_JSON_VARIANT_OBJECT, dispatch_dns_server, offsetof(DNSConfiguration, current_dns_server), 0 },
|
||||
{ "servers", SD_JSON_VARIANT_ARRAY, dispatch_dns_server_array, offsetof(DNSConfiguration, dns_servers), 0 },
|
||||
{ "searchDomains", SD_JSON_VARIANT_ARRAY, dispatch_search_domain_array, offsetof(DNSConfiguration, search_domains), 0 },
|
||||
{ "dnssecSupported", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DNSConfiguration, dnssec_supported), 0 },
|
||||
{ "dnssec", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, dnssec_mode_str), 0 },
|
||||
{ "dnsOverTLS", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, dns_over_tls_mode_str), 0 },
|
||||
{ "llmnr", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, llmnr_mode_str), 0 },
|
||||
{ "mDNS", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, mdns_mode_str), 0 },
|
||||
{ "fallbackServers", SD_JSON_VARIANT_ARRAY, dispatch_dns_server_array, offsetof(DNSConfiguration, fallback_dns_servers), 0 },
|
||||
{ "negativeTrustAnchors", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, offsetof(DNSConfiguration, negative_trust_anchors), 0 },
|
||||
{ "resolvConfMode", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, resolv_conf_mode_str), 0 },
|
||||
{ "scopes", SD_JSON_VARIANT_ARRAY, dispatch_dns_scope_array, offsetof(DNSConfiguration, dns_scopes), 0 },
|
||||
{ "delegate", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DNSConfiguration, delegate), 0 },
|
||||
{},
|
||||
|
||||
};
|
||||
@@ -204,6 +286,8 @@ static int dispatch_dns_configuration(const char *name, sd_json_variant *variant
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
strv_sort(c->negative_trust_anchors);
|
||||
|
||||
*ret = TAKE_PTR(c);
|
||||
|
||||
return 0;
|
||||
@@ -222,7 +306,7 @@ bool dns_is_accessible(DNSConfiguration *c) {
|
||||
if (c->current_dns_server && c->current_dns_server->accessible)
|
||||
return true;
|
||||
|
||||
SET_FOREACH(s, c->dns_servers)
|
||||
ORDERED_SET_FOREACH(s, c->dns_servers)
|
||||
if (s->accessible)
|
||||
return true;
|
||||
|
||||
@@ -237,7 +321,7 @@ bool dns_configuration_contains_search_domain(DNSConfiguration *c, const char *d
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
SET_FOREACH(d, c->search_domains)
|
||||
ORDERED_SET_FOREACH(d, c->search_domains)
|
||||
if (streq(d->name, domain))
|
||||
return true;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "in-addr-util.h"
|
||||
#include "shared-forward.h"
|
||||
|
||||
typedef struct DNSServer {
|
||||
@@ -12,6 +13,7 @@ typedef struct DNSServer {
|
||||
int ifindex;
|
||||
char *server_name;
|
||||
bool accessible;
|
||||
union in_addr_union in_addr;
|
||||
} DNSServer;
|
||||
|
||||
DNSServer* dns_server_free(DNSServer *s);
|
||||
@@ -23,6 +25,18 @@ typedef struct SearchDomain {
|
||||
int ifindex;
|
||||
} SearchDomain;
|
||||
|
||||
typedef struct DNSScope {
|
||||
char *ifname;
|
||||
int ifindex;
|
||||
char *protocol;
|
||||
int family;
|
||||
char *dnssec_mode_str;
|
||||
char *dns_over_tls_mode_str;
|
||||
} DNSScope;
|
||||
|
||||
DNSScope* dns_scope_free(DNSScope *s);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DNSScope*, dns_scope_free);
|
||||
|
||||
SearchDomain* search_domain_free(SearchDomain *d);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(SearchDomain*, search_domain_free);
|
||||
|
||||
@@ -31,8 +45,18 @@ typedef struct DNSConfiguration {
|
||||
int ifindex;
|
||||
bool default_route;
|
||||
DNSServer *current_dns_server;
|
||||
Set *dns_servers;
|
||||
Set *search_domains;
|
||||
OrderedSet *dns_servers;
|
||||
OrderedSet *search_domains;
|
||||
OrderedSet *fallback_dns_servers;
|
||||
Set *dns_scopes;
|
||||
char *dnssec_mode_str;
|
||||
char *dns_over_tls_mode_str;
|
||||
char *llmnr_mode_str;
|
||||
char *mdns_mode_str;
|
||||
char **negative_trust_anchors;
|
||||
char *resolv_conf_mode_str;
|
||||
char *delegate;
|
||||
bool dnssec_supported;
|
||||
} DNSConfiguration;
|
||||
|
||||
DNSConfiguration* dns_configuration_free(DNSConfiguration *c);
|
||||
@@ -61,6 +61,7 @@ shared_sources = files(
|
||||
'dissect-image.c',
|
||||
'dm-util.c',
|
||||
'dns-answer.c',
|
||||
'dns-configuration.c',
|
||||
'dns-domain.c',
|
||||
'dns-packet.c',
|
||||
'dns-question.c',
|
||||
|
||||
@@ -274,6 +274,8 @@ SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(negativeTrustAnchors, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("DNSSEC mode."),
|
||||
SD_VARLINK_DEFINE_FIELD(dnssec, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Indicates if the current DNS server supports DNSSEC. Always false if DNSSEC mode is \"no\"."),
|
||||
SD_VARLINK_DEFINE_FIELD(dnssecSupported, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("DNSOverTLS mode."),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(dnsOverTLS, DNSOverTLSMode, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("LLMNR support."),
|
||||
|
||||
Reference in New Issue
Block a user