resolvectl: show delegate information, too
This commit is contained in:
+211
-12
@@ -1458,7 +1458,7 @@ static int read_dns_server_one(sd_bus_message *m, ReadDNSFlag flags, char **ret)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int map_link_dns_servers_internal(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, ReadDNSFlag flags, void *userdata) {
|
||||
static int map_dns_servers_internal(sd_bus *bus, const char *member, sd_bus_message *m, ReadDNSFlag flags, sd_bus_error *error, void *userdata) {
|
||||
char ***l = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
@@ -1497,11 +1497,11 @@ static int map_link_dns_servers_internal(sd_bus *bus, const char *member, sd_bus
|
||||
}
|
||||
|
||||
static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
return map_link_dns_servers_internal(bus, member, m, error, /* flags = */ 0, userdata);
|
||||
return map_dns_servers_internal(bus, member, m, /* flags = */ 0, error, userdata);
|
||||
}
|
||||
|
||||
static int map_link_dns_servers_ex(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
return map_link_dns_servers_internal(bus, member, m, error, READ_DNS_EXTENDED, userdata);
|
||||
return map_dns_servers_internal(bus, member, m, READ_DNS_EXTENDED, error, userdata);
|
||||
}
|
||||
|
||||
static int map_link_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
@@ -1597,12 +1597,14 @@ static int map_link_domains(sd_bus *bus, const char *member, sd_bus_message *m,
|
||||
return map_domains_internal(bus, member, m, /* with_ifindex= */ false, error, userdata);
|
||||
}
|
||||
|
||||
static int status_print_strv_ifindex(int ifindex, const char *ifname, char **p) {
|
||||
static int status_print_strv_full(int ifindex, const char *ifname, const char *delegate_id, char **p) {
|
||||
const unsigned indent = strlen("Global: "); /* Use the same indentation everywhere to make things nice */
|
||||
int pos1, pos2;
|
||||
|
||||
if (ifname)
|
||||
printf("%s%nLink %i (%s)%n%s:", ansi_highlight(), &pos1, ifindex, ifname, &pos2, ansi_normal());
|
||||
else if (delegate_id)
|
||||
printf("%s%nDelegate %s%n%s:", ansi_highlight(), &pos1, delegate_id, &pos2, ansi_normal());
|
||||
else
|
||||
printf("%s%nGlobal%n%s:", ansi_highlight(), &pos1, &pos2, ansi_normal());
|
||||
|
||||
@@ -1626,8 +1628,16 @@ static int status_print_strv_ifindex(int ifindex, const char *ifname, char **p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_print_strv_ifindex(int ifindex, const char *ifname, char **p) {
|
||||
return status_print_strv_full(ifindex, ifname, NULL, p);
|
||||
}
|
||||
|
||||
static int status_print_strv_delegate(const char *delegate_id, char **p) {
|
||||
return status_print_strv_full(0, NULL, delegate_id, p);
|
||||
}
|
||||
|
||||
static int status_print_strv_global(char **p) {
|
||||
return status_print_strv_ifindex(0, NULL, p);
|
||||
return status_print_strv_full(0, NULL, NULL, p);
|
||||
}
|
||||
|
||||
typedef struct LinkInfo {
|
||||
@@ -2144,18 +2154,13 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_all(sd_bus *bus, StatusMode mode) {
|
||||
static int status_links(sd_bus *bus, StatusMode mode, bool *empty_line) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
bool empty_line = false;
|
||||
int ret = 0, r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = status_global(bus, mode, &empty_line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_open(&rtnl);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to netlink: %m");
|
||||
@@ -2207,11 +2212,205 @@ static int status_all(sd_bus *bus, StatusMode mode) {
|
||||
typesafe_qsort(infos, n_infos, interface_info_compare);
|
||||
|
||||
FOREACH_ARRAY(info, infos, n_infos)
|
||||
RET_GATHER(ret, status_ifindex(bus, info->index, info->name, mode, &empty_line));
|
||||
RET_GATHER(ret, status_ifindex(bus, info->index, info->name, mode, empty_line));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct DelegateInfo {
|
||||
char *current_dns;
|
||||
char **dns;
|
||||
char **domains;
|
||||
bool default_route;
|
||||
} DelegateInfo;
|
||||
|
||||
static void delegate_info_done(DelegateInfo *p) {
|
||||
assert(p);
|
||||
|
||||
free(p->current_dns);
|
||||
strv_free(p->dns);
|
||||
strv_free(p->domains);
|
||||
}
|
||||
|
||||
static int map_delegate_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
return map_dns_servers_internal(bus, member, m, READ_DNS_WITH_IFINDEX|READ_DNS_EXTENDED, error, userdata);
|
||||
}
|
||||
|
||||
static int map_delegate_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
return read_dns_server_one(m, READ_DNS_WITH_IFINDEX|READ_DNS_EXTENDED, userdata);
|
||||
}
|
||||
|
||||
static int map_delegate_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
return map_domains_internal(bus, member, m, /* with_ifindex= */ false, error, userdata);
|
||||
}
|
||||
|
||||
static int status_delegate_one(sd_bus *bus, const char *id, StatusMode mode, bool *empty_line) {
|
||||
|
||||
static const struct bus_properties_map property_map[] = {
|
||||
{ "DNS", "a(iiayqs)", map_delegate_dns_servers, offsetof(DelegateInfo, dns) },
|
||||
{ "CurrentDNSServer", "(iiayqs)", map_delegate_current_dns_server, offsetof(DelegateInfo, current_dns) },
|
||||
{ "Domains", "a(sb)", map_delegate_domains, offsetof(DelegateInfo, domains) },
|
||||
{ "DefaultRoute", "b", NULL, offsetof(DelegateInfo, default_route) },
|
||||
{}
|
||||
};
|
||||
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(delegate_info_done) DelegateInfo delegate_info = {};
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(id);
|
||||
|
||||
r = sd_bus_path_encode("/org/freedesktop/resolve1/dns_delegate", id, &p);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = bus_map_all_properties(
|
||||
bus,
|
||||
"org.freedesktop.resolve1",
|
||||
p,
|
||||
property_map,
|
||||
BUS_MAP_BOOLEAN_AS_BOOL,
|
||||
&error,
|
||||
&m,
|
||||
&delegate_info);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get delegate data for %s: %s", id, bus_error_message(&error, r));
|
||||
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case STATUS_DNS:
|
||||
return status_print_strv_delegate(id, delegate_info.dns);
|
||||
|
||||
case STATUS_DOMAIN:
|
||||
return status_print_strv_delegate(id, delegate_info.domains);
|
||||
|
||||
case STATUS_DEFAULT_ROUTE:
|
||||
printf("%sDelegate %s%s: %s\n",
|
||||
ansi_highlight(), id, ansi_normal(),
|
||||
yes_no(delegate_info.default_route));
|
||||
|
||||
return 0;
|
||||
|
||||
case STATUS_ALL:
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (empty_line && *empty_line)
|
||||
fputc('\n', stdout);
|
||||
|
||||
printf("%sDelegate %s%s\n",
|
||||
ansi_highlight(), id, ansi_normal());
|
||||
|
||||
_cleanup_(table_unrefp) Table *table = table_new_vertical();
|
||||
if (!table)
|
||||
return log_oom();
|
||||
|
||||
if (delegate_info.current_dns) {
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "Current DNS Server",
|
||||
TABLE_STRING, delegate_info.current_dns);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
r = dump_list(table, "DNS Servers", delegate_info.dns);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dump_list(table, "DNS Domain", delegate_info.domains);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "Default Route",
|
||||
TABLE_SET_MINIMUM_WIDTH, 19,
|
||||
TABLE_BOOLEAN, delegate_info.default_route);
|
||||
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return table_log_print_error(r);
|
||||
|
||||
if (empty_line)
|
||||
*empty_line = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_delegates(sd_bus *bus, StatusMode mode, bool *empty_line) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r, ret = 0;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = bus_call_method(bus, bus_resolve_mgr, "ListDelegates", &error, &reply, NULL);
|
||||
if (r < 0) {
|
||||
if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
|
||||
log_debug("Delegates not supported, skipping.");
|
||||
return 0;
|
||||
}
|
||||
return log_error_errno(r, "Failed to list delegates: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "(so)");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
for (;;) {
|
||||
const char *id;
|
||||
|
||||
r = sd_bus_message_read(reply, "(so)", &id, NULL);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (strv_extend(&l, id) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
strv_sort(l);
|
||||
|
||||
STRV_FOREACH(i, l)
|
||||
RET_GATHER(ret, status_delegate_one(bus, *i, mode, empty_line));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int status_all(sd_bus *bus, StatusMode mode) {
|
||||
bool empty_line = false;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = status_global(bus, mode, &empty_line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = status_links(bus, mode, &empty_line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = status_delegates(bus, mode, &empty_line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verb_status(int argc, char **argv, void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
|
||||
Reference in New Issue
Block a user