summaryrefslogtreecommitdiff
path: root/src/resolve/resolvectl.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-05-27 10:50:52 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-07-17 06:59:12 +0900
commit65856bf2083e366ce4e4a2fd9e388bce3f8d3135 (patch)
tree8c42780c08d528e3ea7826a14a0acee613ab9eae /src/resolve/resolvectl.c
parent15761549575027c1cf959a55e25f2c9bcacb79a8 (diff)
downloadsystemd-65856bf2083e366ce4e4a2fd9e388bce3f8d3135.tar.gz
resolvectl: support networkd managed interfaces
Closes #9808.
Diffstat (limited to 'src/resolve/resolvectl.c')
-rw-r--r--src/resolve/resolvectl.c396
1 files changed, 251 insertions, 145 deletions
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index f44d0b8343..8d2ae89281 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -1844,42 +1844,17 @@ static int verb_status(int argc, char **argv, void *userdata) {
return r;
}
-static int log_interface_is_managed(int r, int ifindex) {
- char ifname[IF_NAMESIZE + 1];
-
- return log_error_errno(r,
- "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
- "Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files.",
- strna(format_ifname(ifindex, ifname)));
-}
-
-static int verb_dns(int argc, char **argv, void *userdata) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+static int call_dns(sd_bus *bus, char **dns, const char *destination, const char *path, const char *interface, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
- sd_bus *bus = userdata;
char **p;
int r;
- assert(bus);
-
- if (argc >= 2) {
- r = ifname_mangle(argv[1]);
- if (r < 0)
- return r;
- }
-
- if (arg_ifindex <= 0)
- return status_all(bus, STATUS_DNS);
-
- if (argc < 3)
- return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNS, NULL);
-
r = sd_bus_message_new_method_call(
bus,
&req,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
+ destination,
+ path,
+ interface,
"SetLinkDNS");
if (r < 0)
return bus_log_create_error(r);
@@ -1894,8 +1869,8 @@ static int verb_dns(int argc, char **argv, void *userdata) {
/* If only argument is the empty string, then call SetLinkDNS() with an
* empty list, which will clear the list of domains for an interface. */
- if (!strv_equal(argv + 2, STRV_MAKE(""))) {
- STRV_FOREACH(p, argv + 2) {
+ if (!strv_equal(dns, STRV_MAKE("")))
+ STRV_FOREACH(p, dns) {
struct in_addr_data data;
r = in_addr_from_string_auto(*p, &data.family, &data.address);
@@ -1918,32 +1893,17 @@ static int verb_dns(int argc, char **argv, void *userdata) {
if (r < 0)
return bus_log_create_error(r);
}
- }
r = sd_bus_message_close_container(req);
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_call(bus, req, 0, &error, NULL);
- if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
- if (arg_ifindex_permissive &&
- sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
- return 0;
-
- return log_error_errno(r, "Failed to set DNS configuration: %s", bus_error_message(&error, r));
- }
-
- return 0;
+ return sd_bus_call(bus, req, 0, error, NULL);
}
-static int verb_domain(int argc, char **argv, void *userdata) {
+static int verb_dns(int argc, char **argv, void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
sd_bus *bus = userdata;
- char **p;
int r;
assert(bus);
@@ -1955,17 +1915,47 @@ static int verb_domain(int argc, char **argv, void *userdata) {
}
if (arg_ifindex <= 0)
- return status_all(bus, STATUS_DOMAIN);
+ return status_all(bus, STATUS_DNS);
if (argc < 3)
- return status_ifindex(bus, arg_ifindex, NULL, STATUS_DOMAIN, NULL);
+ return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNS, NULL);
+
+ r = call_dns(bus, argv + 2,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ &error);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = call_dns(bus, argv + 2,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ &error);
+ }
+ if (r < 0) {
+ if (arg_ifindex_permissive &&
+ sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
+ return 0;
+
+ return log_error_errno(r, "Failed to set DNS configuration: %s", bus_error_message(&error, r));
+ }
+
+ return 0;
+}
+
+static int call_domain(sd_bus *bus, char **domain, const char *destination, const char *path, const char *interface, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
+ char **p;
+ int r;
r = sd_bus_message_new_method_call(
bus,
&req,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
+ destination,
+ path,
+ interface,
"SetLinkDomains");
if (r < 0)
return bus_log_create_error(r);
@@ -1980,8 +1970,8 @@ static int verb_domain(int argc, char **argv, void *userdata) {
/* If only argument is the empty string, then call SetLinkDomains() with an
* empty list, which will clear the list of domains for an interface. */
- if (!strv_equal(argv + 2, STRV_MAKE(""))) {
- STRV_FOREACH(p, argv + 2) {
+ if (!strv_equal(domain, STRV_MAKE("")))
+ STRV_FOREACH(p, domain) {
const char *n;
n = **p == '~' ? *p + 1 : *p;
@@ -1998,17 +1988,48 @@ static int verb_domain(int argc, char **argv, void *userdata) {
if (r < 0)
return bus_log_create_error(r);
}
- }
r = sd_bus_message_close_container(req);
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_call(bus, req, 0, &error, NULL);
- if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
+ return sd_bus_call(bus, req, 0, error, NULL);
+}
+
+static int verb_domain(int argc, char **argv, void *userdata) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus = userdata;
+ int r;
+
+ assert(bus);
+
+ if (argc >= 2) {
+ r = ifname_mangle(argv[1]);
+ if (r < 0)
+ return r;
+ }
+
+ if (arg_ifindex <= 0)
+ return status_all(bus, STATUS_DOMAIN);
+
+ if (argc < 3)
+ return status_ifindex(bus, arg_ifindex, NULL, STATUS_DOMAIN, NULL);
+
+ r = call_domain(bus, argv + 2,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ &error);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+ r = call_domain(bus, argv + 2,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ &error);
+ }
+ if (r < 0) {
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2042,18 +2063,29 @@ static int verb_default_route(int argc, char **argv, void *userdata) {
if (b < 0)
return log_error_errno(b, "Failed to parse boolean argument: %s", argv[2]);
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkDefaultRoute",
- &error,
- NULL,
- "ib", arg_ifindex, b);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "SetLinkDefaultRoute",
+ &error,
+ NULL,
+ "ib", arg_ifindex, b);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "SetLinkDefaultRoute",
+ &error,
+ NULL,
+ "ib", arg_ifindex, b);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2083,18 +2115,29 @@ static int verb_llmnr(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_LLMNR, NULL);
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkLLMNR",
- &error,
- NULL,
- "is", arg_ifindex, argv[2]);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "SetLinkLLMNR",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "SetLinkLLMNR",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2124,18 +2167,29 @@ static int verb_mdns(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_MDNS, NULL);
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkMulticastDNS",
- &error,
- NULL,
- "is", arg_ifindex, argv[2]);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "SetLinkMulticastDNS",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "SetLinkMulticastDNS",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2165,18 +2219,29 @@ static int verb_dns_over_tls(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_PRIVATE, NULL);
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkDNSOverTLS",
- &error,
- NULL,
- "is", arg_ifindex, argv[2]);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "SetLinkDNSOverTLS",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "SetLinkDNSOverTLS",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2206,18 +2271,29 @@ static int verb_dnssec(int argc, char **argv, void *userdata) {
if (argc < 3)
return status_ifindex(bus, arg_ifindex, NULL, STATUS_DNSSEC, NULL);
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkDNSSEC",
- &error,
- NULL,
- "is", arg_ifindex, argv[2]);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "SetLinkDNSSEC",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "SetLinkDNSSEC",
+ &error,
+ NULL,
+ "is", arg_ifindex, argv[2]);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2228,9 +2304,33 @@ static int verb_dnssec(int argc, char **argv, void *userdata) {
return 0;
}
+static int call_nta(sd_bus *bus, char **nta, const char *destination, const char *path, const char *interface, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
+ int r;
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &req,
+ destination,
+ path,
+ interface,
+ "SetLinkDNSSECNegativeTrustAnchors");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(req, "i", arg_ifindex);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(req, nta);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return sd_bus_call(bus, req, 0, error, NULL);
+}
+
static int verb_nta(int argc, char **argv, void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL;
sd_bus *bus = userdata;
char **p;
int r;
@@ -2265,29 +2365,21 @@ static int verb_nta(int argc, char **argv, void *userdata) {
}
}
- r = sd_bus_message_new_method_call(
- bus,
- &req,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "SetLinkDNSSECNegativeTrustAnchors");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(req, "i", arg_ifindex);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append_strv(req, clear ? NULL : argv + 2);
- if (r < 0)
- return bus_log_create_error(r);
+ r = call_nta(bus, clear ? NULL : argv + 2,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ &error);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
- r = sd_bus_call(bus, req, 0, &error, NULL);
+ r = call_nta(bus, clear ? NULL : argv + 2,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ &error);
+ }
if (r < 0) {
- if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
- return log_interface_is_managed(r, arg_ifindex);
-
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))
return 0;
@@ -2314,14 +2406,28 @@ static int verb_revert_link(int argc, char **argv, void *userdata) {
if (arg_ifindex <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Interface argument required.");
- r = sd_bus_call_method(bus,
- "org.freedesktop.resolve1",
- "/org/freedesktop/resolve1",
- "org.freedesktop.resolve1.Manager",
- "RevertLink",
- &error,
- NULL,
- "i", arg_ifindex);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "RevertLink",
+ &error,
+ NULL,
+ "i", arg_ifindex);
+ if (r < 0 && sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY)) {
+ sd_bus_error_free(&error);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.network1",
+ "/org/freedesktop/network1",
+ "org.freedesktop.network1.Manager",
+ "RevertLinkDNS",
+ &error,
+ NULL,
+ "i", arg_ifindex);
+ }
if (r < 0) {
if (arg_ifindex_permissive &&
sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK))