resolve: make PrivateDNS configurable per link
authorIwan Timmer <irtimmer@gmail.com>
Fri, 4 May 2018 15:31:16 +0000 (17:31 +0200)
committerIwan Timmer <irtimmer@gmail.com>
Mon, 11 Jun 2018 19:35:58 +0000 (21:35 +0200)
Like with DNSSec, make PrivateDNS configurable per link, so you can have trusted and untrusted links.

14 files changed:
src/libsystemd/sd-network/sd-network.c
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/resolve/resolvectl.c
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-link-bus.c
src/resolve/resolved-link-bus.h
src/resolve/resolved-link.c
src/resolve/resolved-link.h
src/resolve/resolved.conf.in
src/systemd/sd-network.h

index 4f3f6f9..412a8ae 100644 (file)
@@ -178,6 +178,10 @@ _public_ int sd_network_link_get_mdns(int ifindex, char **mdns) {
         return network_link_get_string(ifindex, "MDNS", mdns);
 }
 
+_public_ int sd_network_link_get_private_dns(int ifindex, char **private_dns) {
+        return network_link_get_string(ifindex, "PRIVATE_DNS", private_dns);
+}
+
 _public_ int sd_network_link_get_dnssec(int ifindex, char **dnssec) {
         return network_link_get_string(ifindex, "DNSSEC", dnssec);
 }
index c049640..805a4a7 100644 (file)
@@ -3762,6 +3762,10 @@ int link_save(Link *link) {
                 fprintf(f, "MDNS=%s\n",
                         resolve_support_to_string(link->network->mdns));
 
+                if (link->network->private_dns_mode != _PRIVATE_DNS_MODE_INVALID)
+                        fprintf(f, "PRIVATE_DNS=%s\n",
+                                private_dns_mode_to_string(link->network->private_dns_mode));
+
                 if (link->network->dnssec_mode != _DNSSEC_MODE_INVALID)
                         fprintf(f, "DNSSEC=%s\n",
                                 dnssec_mode_to_string(link->network->dnssec_mode));
index e6ca663..38d168a 100644 (file)
@@ -60,6 +60,7 @@ Network.Domains,                        config_parse_domains,
 Network.DNS,                            config_parse_dns,                               0,                             0
 Network.LLMNR,                          config_parse_resolve_support,                   0,                             offsetof(Network, llmnr)
 Network.MulticastDNS,                   config_parse_resolve_support,                   0,                             offsetof(Network, mdns)
+Network.PrivateDNS,                     config_parse_private_dns_mode,                  0,                             offsetof(Network, private_dns_mode)
 Network.DNSSEC,                         config_parse_dnssec_mode,                       0,                             offsetof(Network, dnssec_mode)
 Network.DNSSECNegativeTrustAnchors,     config_parse_dnssec_negative_trust_anchors,     0,                             0
 Network.NTP,                            config_parse_ntp,                               0,                             offsetof(Network, ntp)
index b2a75c7..fc7d9a3 100644 (file)
@@ -236,6 +236,7 @@ static int network_load_one(Manager *manager, const char *filename) {
         network->llmnr = RESOLVE_SUPPORT_YES;
         network->mdns = RESOLVE_SUPPORT_NO;
         network->dnssec_mode = _DNSSEC_MODE_INVALID;
+        network->private_dns_mode = _PRIVATE_DNS_MODE_INVALID;
 
         network->link_local = ADDRESS_FAMILY_IPV6;
 
index 5b6b40d..3136835 100644 (file)
@@ -261,6 +261,7 @@ struct Network {
         ResolveSupport llmnr;
         ResolveSupport mdns;
         DnssecMode dnssec_mode;
+        PrivateDnsMode private_dns_mode;
         Set *dnssec_negative_trust_anchors;
 
         LIST_FIELDS(Network, networks);
index 26b3a81..750001d 100644 (file)
@@ -56,6 +56,7 @@ char **arg_set_dns = NULL;
 char **arg_set_domain = NULL;
 static const char *arg_set_llmnr = NULL;
 static const char *arg_set_mdns = NULL;
+static const char *arg_set_private_dns = NULL;
 static const char *arg_set_dnssec = NULL;
 static char **arg_set_nta = NULL;
 
@@ -65,6 +66,7 @@ typedef enum StatusMode {
         STATUS_DOMAIN,
         STATUS_LLMNR,
         STATUS_MDNS,
+        STATUS_PRIVATE,
         STATUS_DNSSEC,
         STATUS_NTA,
 } StatusMode;
@@ -1337,6 +1339,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
                 uint64_t scopes_mask;
                 const char *llmnr;
                 const char *mdns;
+                const char *private_dns;
                 const char *dnssec;
                 char *current_dns;
                 char **dns;
@@ -1352,6 +1355,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
                 { "Domains",                    "a(sb)",  map_link_domains,            offsetof(struct link_info, domains)          },
                 { "LLMNR",                      "s",      NULL,                        offsetof(struct link_info, llmnr)            },
                 { "MulticastDNS",               "s",      NULL,                        offsetof(struct link_info, mdns)             },
+                { "PrivateDNS",                 "s",      NULL,                        offsetof(struct link_info, private_dns)      },
                 { "DNSSEC",                     "s",      NULL,                        offsetof(struct link_info, dnssec)           },
                 { "DNSSECNegativeTrustAnchors", "as",     NULL,                        offsetof(struct link_info, ntas)             },
                 { "DNSSECSupported",            "b",      NULL,                        offsetof(struct link_info, dnssec_supported) },
@@ -1430,6 +1434,15 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
                 goto finish;
         }
 
+        if (mode == STATUS_PRIVATE) {
+                printf("%sLink %i (%s)%s: %s\n",
+                       ansi_highlight(), ifindex, name, ansi_normal(),
+                       strna(link_info.private_dns));
+
+                r = 0;
+                goto finish;
+        }
+
         if (mode == STATUS_DNSSEC) {
                 printf("%sLink %i (%s)%s: %s\n",
                        ansi_highlight(), ifindex, name, ansi_normal(),
@@ -1457,10 +1470,12 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
 
         printf("       LLMNR setting: %s\n"
                "MulticastDNS setting: %s\n"
+               "  PrivateDNS setting: %s\n"
                "      DNSSEC setting: %s\n"
                "    DNSSEC supported: %s\n",
                strna(link_info.llmnr),
                strna(link_info.mdns),
+               strna(link_info.private_dns),
                strna(link_info.dnssec),
                yes_no(link_info.dnssec_supported));
 
@@ -1602,6 +1617,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
                 char **ntas;
                 const char *llmnr;
                 const char *mdns;
+                const char *private_dns;
                 const char *dnssec;
                 bool dnssec_supported;
         } global_info = {};
@@ -1614,6 +1630,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
                 { "DNSSECNegativeTrustAnchors", "as",      NULL,                          offsetof(struct global_info, ntas)             },
                 { "LLMNR",                      "s",       NULL,                          offsetof(struct global_info, llmnr)            },
                 { "MulticastDNS",               "s",       NULL,                          offsetof(struct global_info, mdns)             },
+                { "PrivateDNS",                 "s",       NULL,                          offsetof(struct global_info, private_dns)      },
                 { "DNSSEC",                     "s",       NULL,                          offsetof(struct global_info, dnssec)           },
                 { "DNSSECSupported",            "b",       NULL,                          offsetof(struct global_info, dnssec_supported) },
                 {}
@@ -1673,6 +1690,14 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
                 goto finish;
         }
 
+        if (mode == STATUS_PRIVATE) {
+                printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
+                       strna(global_info.private_dns));
+
+                r = 0;
+                goto finish;
+        }
+
         if (mode == STATUS_DNSSEC) {
                 printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
                        strna(global_info.dnssec));
@@ -1685,10 +1710,12 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
 
         printf("       LLMNR setting: %s\n"
                "MulticastDNS setting: %s\n"
+               "  PrivateDNS setting: %s\n"
                "      DNSSEC setting: %s\n"
                "    DNSSEC supported: %s\n",
                strna(global_info.llmnr),
                strna(global_info.mdns),
+               strna(global_info.private_dns),
                strna(global_info.dnssec),
                yes_no(global_info.dnssec_supported));
 
@@ -2081,6 +2108,50 @@ static int verb_mdns(int argc, char **argv, void *userdata) {
         return 0;
 }
 
+static int verb_private_dns(int argc, char **argv, void *userdata) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        sd_bus *bus = userdata;
+        int ifindex, r;
+
+        assert(bus);
+
+        if (argc <= 1)
+                return status_all(bus, STATUS_PRIVATE);
+
+        ifindex = parse_ifindex_with_warn(argv[1]);
+        if (ifindex < 0)
+                return ifindex;
+
+        if (ifindex == LOOPBACK_IFINDEX) {
+                log_error("Interface can't be the loopback interface (lo). Sorry.");
+                return -EINVAL;
+        }
+
+        if (argc == 2)
+                return status_ifindex(bus, ifindex, NULL, STATUS_PRIVATE, NULL);
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.resolve1",
+                               "/org/freedesktop/resolve1",
+                               "org.freedesktop.resolve1.Manager",
+                               "SetLinkPrivateDNS",
+                               &error,
+                               NULL,
+                               "is", ifindex, argv[2]);
+        if (r < 0) {
+                if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY))
+                        return log_interface_is_managed(r, 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 PrivateDNS configuration: %s", bus_error_message(&error, r));
+        }
+
+        return 0;
+}
+
 static int verb_dnssec(int argc, char **argv, void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus *bus = userdata;
@@ -2283,6 +2354,7 @@ static void compat_help(void) {
                "     --set-domain=DOMAIN    Set per-interface search domain\n"
                "     --set-llmnr=MODE       Set per-interface LLMNR mode\n"
                "     --set-mdns=MODE        Set per-interface MulticastDNS mode\n"
+               "     --set-privatedns=MODE  Set per-interface PrivateDNS mode\n"
                "     --set-dnssec=MODE      Set per-interface DNSSEC mode\n"
                "     --set-nta=DOMAIN       Set per-interface DNSSEC NTA\n"
                "     --revert               Revert per-interface configuration\n"
@@ -2326,6 +2398,7 @@ static void native_help(void) {
                "  domain [LINK [DOMAIN...]]    Get/set per-interface search domain\n"
                "  llmnr [LINK [MODE]]          Get/set per-interface LLMNR mode\n"
                "  mdns [LINK [MODE]]           Get/set per-interface MulticastDNS mode\n"
+               "  privatedns [LINK [MODE]]     Get/set per-interface PrivateDNS mode\n"
                "  dnssec [LINK [MODE]]         Get/set per-interface DNSSEC mode\n"
                "  nta [LINK [DOMAIN...]]       Get/set per-interface DNSSEC NTA\n"
                "  revert LINK                  Revert per-interface configuration\n"
@@ -2359,6 +2432,7 @@ static int compat_parse_argv(int argc, char *argv[]) {
                 ARG_SET_DOMAIN,
                 ARG_SET_LLMNR,
                 ARG_SET_MDNS,
+                ARG_SET_PRIVATE,
                 ARG_SET_DNSSEC,
                 ARG_SET_NTA,
                 ARG_REVERT_LINK,
@@ -2390,6 +2464,7 @@ static int compat_parse_argv(int argc, char *argv[]) {
                 { "set-domain",            required_argument, NULL, ARG_SET_DOMAIN            },
                 { "set-llmnr",             required_argument, NULL, ARG_SET_LLMNR             },
                 { "set-mdns",              required_argument, NULL, ARG_SET_MDNS              },
+                { "set-privatedns",        required_argument, NULL, ARG_SET_PRIVATE       },
                 { "set-dnssec",            required_argument, NULL, ARG_SET_DNSSEC            },
                 { "set-nta",               required_argument, NULL, ARG_SET_NTA               },
                 { "revert",                no_argument,       NULL, ARG_REVERT_LINK           },
@@ -2608,6 +2683,11 @@ static int compat_parse_argv(int argc, char *argv[]) {
                         arg_mode = MODE_SET_LINK;
                         break;
 
+                case ARG_SET_PRIVATE:
+                        arg_set_private_dns = optarg;
+                        arg_mode = MODE_SET_LINK;
+                        break;
+
                 case ARG_SET_DNSSEC:
                         arg_set_dnssec = optarg;
                         arg_mode = MODE_SET_LINK;
@@ -2651,7 +2731,7 @@ static int compat_parse_argv(int argc, char *argv[]) {
         if (IN_SET(arg_mode, MODE_SET_LINK, MODE_REVERT_LINK)) {
 
                 if (arg_ifindex <= 0) {
-                        log_error("--set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-dnssec=, --set-nta= and --revert require --interface=.");
+                        log_error("--set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-privatedns=, --set-dnssec=, --set-nta= and --revert require --interface=.");
                         return -EINVAL;
                 }
 
@@ -2877,6 +2957,7 @@ static int native_main(int argc, char *argv[], sd_bus *bus) {
                 { "domain",                VERB_ANY, VERB_ANY, 0,            verb_domain           },
                 { "llmnr",                 VERB_ANY, 3,        0,            verb_llmnr            },
                 { "mdns",                  VERB_ANY, 3,        0,            verb_mdns             },
+                { "privatedns",            VERB_ANY, 3,        0,            verb_private_dns      },
                 { "dnssec",                VERB_ANY, 3,        0,            verb_dnssec           },
                 { "nta",                   VERB_ANY, VERB_ANY, 0,            verb_nta              },
                 { "revert",                2,        2,        0,            verb_revert_link      },
@@ -2969,6 +3050,12 @@ static int compat_main(int argc, char *argv[], sd_bus *bus) {
                                 return r;
                 }
 
+                if (arg_set_private_dns) {
+                        r = translate("privatedns", arg_ifname, 1, (char **) &arg_set_private_dns, bus);
+                        if (r < 0)
+                                return r;
+                }
+
                 if (arg_set_dnssec) {
                         r = translate("dnssec", arg_ifname, 1, (char **) &arg_set_dnssec, bus);
                         if (r < 0)
index ba4c47c..78e03d8 100644 (file)
@@ -52,12 +52,14 @@ int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int
                  * not update it from the on, even if the setting
                  * changes. */
 
-                if (l)
+                if (l) {
                         s->dnssec_mode = link_get_dnssec_mode(l);
-                else
+                        s->private_dns_mode = link_get_private_dns_mode(l);
+                } else {
                         s->dnssec_mode = manager_get_dnssec_mode(m);
+                        s->private_dns_mode = manager_get_private_dns_mode(m);
+                }
 
-                s->private_dns_mode = manager_get_private_dns_mode(m);
         } else {
                 s->dnssec_mode = DNSSEC_NO;
                 s->private_dns_mode = PRIVATE_DNS_NO;
index 7e0d2a0..164f460 100644 (file)
@@ -831,6 +831,9 @@ DnssecMode dns_server_get_dnssec_mode(DnsServer *s) {
 PrivateDnsMode dns_server_get_private_dns_mode(DnsServer *s) {
         assert(s);
 
+        if (s->link)
+                return link_get_private_dns_mode(s->link);
+
         return manager_get_private_dns_mode(s->manager);
 }
 
index a1fc3ad..3e06f1f 100644 (file)
 static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
 static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
 
+static int property_get_private_dns_mode(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Link *l = userdata;
+
+        assert(reply);
+        assert(l);
+
+        return sd_bus_message_append(reply, "s", private_dns_mode_to_string(link_get_private_dns_mode(l)));
+}
+
 static int property_get_dns(
                 sd_bus *bus,
                 const char *path,
@@ -402,6 +419,38 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
         return sd_bus_reply_method_return(message, NULL);
 }
 
+int bus_link_method_set_private_dns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Link *l = userdata;
+        const char *private_dns;
+        PrivateDnsMode mode;
+        int r;
+
+        assert(message);
+        assert(l);
+
+        r = verify_unmanaged_link(l, error);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(message, "s", &private_dns);
+        if (r < 0)
+                return r;
+
+        if (isempty(private_dns))
+                mode = _PRIVATE_DNS_MODE_INVALID;
+        else {
+                mode = private_dns_mode_from_string(private_dns);
+                if (mode < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PrivateDNS setting: %s", private_dns);
+        }
+
+        link_set_private_dns_mode(l, mode);
+
+        (void) link_save_user(l);
+
+        return sd_bus_reply_method_return(message, NULL);
+}
+
 int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Link *l = userdata;
         const char *dnssec;
@@ -508,6 +557,7 @@ const sd_bus_vtable link_vtable[] = {
         SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0),
         SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Link, llmnr_support), 0),
         SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Link, mdns_support), 0),
+        SD_BUS_PROPERTY("PrivateDNS", "s", property_get_private_dns_mode, 0, 0),
         SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, 0, 0),
         SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
         SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
@@ -516,6 +566,7 @@ const sd_bus_vtable link_vtable[] = {
         SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
         SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
         SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
+        SD_BUS_METHOD("SetPrivateDNS", "s", NULL, bus_link_method_set_private_dns, 0),
         SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
         SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0),
         SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0),
index e55c007..1632621 100644 (file)
@@ -21,6 +21,7 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
 int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_link_method_set_private_dns(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error *error);
index ccce2fd..aceea66 100644 (file)
@@ -41,6 +41,7 @@ int link_new(Manager *m, Link **ret, int ifindex) {
         l->llmnr_support = RESOLVE_SUPPORT_YES;
         l->mdns_support = RESOLVE_SUPPORT_NO;
         l->dnssec_mode = _DNSSEC_MODE_INVALID;
+        l->private_dns_mode = _PRIVATE_DNS_MODE_INVALID;
         l->operstate = IF_OPER_UNKNOWN;
 
         if (asprintf(&l->state_file, "/run/systemd/resolve/netif/%i", ifindex) < 0)
@@ -65,6 +66,7 @@ void link_flush_settings(Link *l) {
         l->llmnr_support = RESOLVE_SUPPORT_YES;
         l->mdns_support = RESOLVE_SUPPORT_NO;
         l->dnssec_mode = _DNSSEC_MODE_INVALID;
+        l->private_dns_mode = _PRIVATE_DNS_MODE_INVALID;
 
         dns_server_unlink_all(l->dns_servers);
         dns_search_domain_unlink_all(l->search_domains);
@@ -352,6 +354,46 @@ clear:
         return r;
 }
 
+void link_set_private_dns_mode(Link *l, PrivateDnsMode mode) {
+
+        assert(l);
+
+#if ! HAVE_GNUTLS
+        if (mode != PRIVATE_DNS_NO)
+                log_warning("Private DNS option for the link cannot be set to opportunistic when systemd-resolved is built without gnutls support. Turning off Private DNS support.");
+        return;
+#endif
+
+        l->private_dns_mode = mode;
+}
+
+static int link_update_private_dns_mode(Link *l) {
+        _cleanup_free_ char *b = NULL;
+        int r;
+
+        assert(l);
+
+        r = sd_network_link_get_private_dns(l->ifindex, &b);
+        if (r == -ENODATA) {
+                r = 0;
+                goto clear;
+        }
+        if (r < 0)
+                goto clear;
+
+        l->private_dns_mode = private_dns_mode_from_string(b);
+        if (l->private_dns_mode < 0) {
+                r = -EINVAL;
+                goto clear;
+        }
+
+        return 0;
+
+clear:
+        l->private_dns_mode = _PRIVATE_DNS_MODE_INVALID;
+        return r;
+}
+
 void link_set_dnssec_mode(Link *l, DnssecMode mode) {
 
         assert(l);
@@ -559,6 +601,10 @@ static void link_read_settings(Link *l) {
         if (r < 0)
                 log_warning_errno(r, "Failed to read mDNS support for interface %s, ignoring: %m", l->name);
 
+        r = link_update_private_dns_mode(l);
+        if (r < 0)
+                log_warning_errno(r, "Failed to read Private DNS mode for interface %s, ignoring: %m", l->name);
+
         r = link_update_dnssec_mode(l);
         if (r < 0)
                 log_warning_errno(r, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l->name);
@@ -692,6 +738,15 @@ void link_next_dns_server(Link *l) {
         link_set_dns_server(l, l->dns_servers);
 }
 
+PrivateDnsMode link_get_private_dns_mode(Link *l) {
+        assert(l);
+
+        if (l->private_dns_mode != _PRIVATE_DNS_MODE_INVALID)
+                return l->private_dns_mode;
+
+        return manager_get_private_dns_mode(l->manager);
+}
+
 DnssecMode link_get_dnssec_mode(Link *l) {
         assert(l);
 
index d8e65cd..cedcdd6 100644 (file)
@@ -59,6 +59,7 @@ struct Link {
 
         ResolveSupport llmnr_support;
         ResolveSupport mdns_support;
+        PrivateDnsMode private_dns_mode;
         DnssecMode dnssec_mode;
         Set *dnssec_negative_trust_anchors;
 
@@ -90,6 +91,7 @@ void link_add_rrs(Link *l, bool force_remove);
 
 void link_flush_settings(Link *l);
 void link_set_dnssec_mode(Link *l, DnssecMode mode);
+void link_set_private_dns_mode(Link *l, PrivateDnsMode mode);
 void link_allocate_scopes(Link *l);
 
 DnsServer* link_set_dns_server(Link *l, DnsServer *s);
@@ -99,6 +101,8 @@ void link_next_dns_server(Link *l);
 DnssecMode link_get_dnssec_mode(Link *l);
 bool link_dnssec_supported(Link *l);
 
+PrivateDnsMode link_get_private_dns_mode(Link *l);
+
 int link_save_user(Link *l);
 int link_load_user(Link *l);
 void link_remove_user(Link *l);
index 86b37cc..60c4808 100644 (file)
@@ -18,6 +18,6 @@
 #LLMNR=yes
 #MulticastDNS=yes
 #DNSSEC=@DEFAULT_DNSSEC_MODE@
-#PrivateDNS=@DEFAULT_PRIVATE_DNS@
+#PrivateDNS=@DEFAULT_PRIVATE_DNS_MODE@
 #Cache=yes
 #DNSStubListener=udp
index 2d48946..64bfb4f 100644 (file)
@@ -129,6 +129,14 @@ int sd_network_link_get_llmnr(int ifindex, char **llmnr);
  */
 int sd_network_link_get_mdns(int ifindex, char **mdns);
 
+/* Indicates whether or not Private DNS should be enabled for the
+ * link.
+ * Possible levels of support: strict, no, opportunistic
+ * Possible return codes:
+ *   -ENODATA: networkd is not aware of the link
+ */
+int sd_network_link_get_private_dns(int ifindex, char **private_dns);
+
 /* Indicates whether or not DNSSEC should be enabled for the link
  * Possible levels of support: yes, no, allow-downgrade
  * Possible return codes: