diff --git a/introspection/org.freedesktop.NetworkManager.DnsManager.xml b/introspection/org.freedesktop.NetworkManager.DnsManager.xml
index 8cc3eba21..3a0c757bd 100644
--- a/introspection/org.freedesktop.NetworkManager.DnsManager.xml
+++ b/introspection/org.freedesktop.NetworkManager.DnsManager.xml
@@ -22,5 +22,18 @@
-->
+
+
+
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index aee6e8fc8..ac6b0c19b 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -42,6 +42,8 @@
#include "nm-ip6-config.h"
#include "NetworkManagerUtils.h"
#include "nm-config.h"
+#include "devices/nm-device.h"
+#include "nm-manager.h"
#include "nm-dns-plugin.h"
#include "nm-dns-dnsmasq.h"
@@ -87,6 +89,7 @@ enum {
NM_GOBJECT_PROPERTIES_DEFINE (NMDnsManager,
PROP_MODE,
PROP_RC_MANAGER,
+ PROP_CONFIGURATION,
);
static guint signals[LAST_SIGNAL] = { 0 };
@@ -123,6 +126,7 @@ typedef enum {
typedef struct {
GPtrArray *configs;
+ GVariant *config_variant;
NMDnsIPConfigData *best_conf4, *best_conf6;
gboolean need_sort;
@@ -1204,6 +1208,9 @@ update_dns (NMDnsManager *self,
if (update && result == SR_SUCCESS)
g_signal_emit (self, signals[CONFIG_CHANGED], 0);
+ g_clear_pointer (&priv->config_variant, g_variant_unref);
+ _notify (self, PROP_CONFIGURATION);
+
if (searches)
g_strfreev (searches);
if (options)
@@ -1773,6 +1780,198 @@ config_changed_cb (NMConfig *config,
}
}
+static GVariant *
+_get_global_config_variant (NMGlobalDnsConfig *global)
+{
+ NMGlobalDnsDomain *domain;
+ GVariantBuilder builder;
+ guint i, num;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
+ num = nm_global_dns_config_get_num_domains (global);
+ for (i = 0; i < num; i++) {
+ GVariantBuilder conf_builder;
+ GVariantBuilder item_builder;
+ const char *domain_name;
+ const char * const *servers;
+
+ g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}"));
+
+ domain = nm_global_dns_config_get_domain (global, i);
+ domain_name = nm_global_dns_domain_get_name (domain);
+
+ if (domain_name && !nm_streq0 (domain_name, "*")) {
+ g_variant_builder_init (&item_builder, G_VARIANT_TYPE ("as"));
+ g_variant_builder_add (&item_builder,
+ "s",
+ domain_name);
+ g_variant_builder_add (&conf_builder,
+ "{sv}",
+ "domains",
+ g_variant_builder_end (&item_builder));
+ }
+
+ g_variant_builder_init (&item_builder, G_VARIANT_TYPE ("as"));
+ for (servers = nm_global_dns_domain_get_servers (domain); *servers; servers++) {
+ g_variant_builder_add (&item_builder,
+ "s",
+ *servers);
+ }
+ g_variant_builder_add (&conf_builder,
+ "{sv}",
+ "nameservers",
+ g_variant_builder_end (&item_builder));
+
+ g_variant_builder_add (&conf_builder,
+ "{sv}",
+ "priority",
+ g_variant_new_int32 (NM_DNS_PRIORITY_DEFAULT_NORMAL));
+
+ g_variant_builder_add (&builder, "a{sv}", &conf_builder);
+ }
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+}
+
+static GVariant *
+_get_config_variant (NMDnsManager *self)
+{
+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ NMGlobalDnsConfig *global_config;
+ GVariantBuilder builder;
+ NMConfigData *data;
+ guint i, j;
+
+ if (priv->config_variant)
+ return priv->config_variant;
+
+ data = nm_config_get_data (priv->config);
+ global_config = nm_config_data_get_global_dns_config (data);
+ if (global_config) {
+ priv->config_variant = _get_global_config_variant (global_config);
+ _LOGT ("current configuration: %s", g_variant_print (priv->config_variant, TRUE));
+ return priv->config_variant;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
+
+ for (i = 0; i < priv->configs->len; i++) {
+ NMDnsIPConfigData *current = priv->configs->pdata[i];
+ GVariantBuilder entry_builder;
+ GVariantBuilder strv_builder;
+ gboolean v4 = NM_IS_IP4_CONFIG (current->config);
+ gint priority;
+
+ g_variant_builder_init (&entry_builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as"));
+
+ if (v4) {
+ NMIP4Config *config = NM_IP4_CONFIG (current->config);
+ guint num = nm_ip4_config_get_num_nameservers (config);
+ guint32 ns;
+
+ if (!num)
+ continue;
+
+ /* Add nameservers */
+ for (j = 0; j < num; j++) {
+ ns = nm_ip4_config_get_nameserver (config, j);
+ g_variant_builder_add (&strv_builder,
+ "s",
+ nm_utils_inet4_ntop (ns, NULL));
+ }
+
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "nameservers",
+ g_variant_builder_end (&strv_builder));
+
+ /* Add domains */
+ g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as"));
+ num = nm_ip4_config_get_num_domains (config);
+ for (j = 0; j < num; j++) {
+ g_variant_builder_add (&strv_builder,
+ "s",
+ nm_ip4_config_get_domain (config, j));
+ }
+
+ if (num) {
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "domains",
+ g_variant_builder_end (&strv_builder));
+ }
+
+ priority = nm_ip4_config_get_dns_priority (config);
+ } else {
+ NMIP6Config *config = NM_IP6_CONFIG (current->config);
+ guint num = nm_ip6_config_get_num_nameservers (config);
+ const struct in6_addr *ns;
+
+ if (!num)
+ continue;
+
+ /* Add nameservers */
+ for (j = 0; j < num; j++) {
+ ns = nm_ip6_config_get_nameserver (config, j);
+ g_variant_builder_add (&strv_builder,
+ "s",
+ nm_utils_inet6_ntop (ns, NULL));
+ }
+
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "nameservers",
+ g_variant_builder_end (&strv_builder));
+
+ /* Add domains */
+ g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as"));
+ num = nm_ip6_config_get_num_domains (config);
+ for (j = 0; j < num; j++) {
+ g_variant_builder_add (&strv_builder,
+ "s",
+ nm_ip6_config_get_domain (config, j));
+ }
+
+ if (num) {
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "domains",
+ g_variant_builder_end (&strv_builder));
+ }
+
+ priority = nm_ip6_config_get_dns_priority (config);
+ }
+
+ /* Add device */
+ if (current->iface) {
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "interface",
+ g_variant_new_string (current->iface));
+ }
+
+ /* Add priority */
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "priority",
+ g_variant_new_int32 (priority));
+
+ /* Add VPN */
+ g_variant_builder_add (&entry_builder,
+ "{sv}",
+ "vpn",
+ g_variant_new_boolean (current->type == NM_DNS_IP_CONFIG_TYPE_VPN));
+
+ g_variant_builder_add (&builder, "a{sv}", &entry_builder);
+ }
+
+ priv->config_variant = g_variant_ref_sink (g_variant_builder_end (&builder));
+ _LOGT ("current configuration: %s", g_variant_print (priv->config_variant, TRUE));
+
+ return priv->config_variant;
+}
+
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -1787,6 +1986,9 @@ get_property (GObject *object, guint prop_id,
case PROP_RC_MANAGER:
g_value_set_string (value, _rc_manager_to_string (priv->rc_manager));
break;
+ case PROP_CONFIGURATION:
+ g_value_set_variant (value, _get_config_variant (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1893,6 +2095,13 @@ nm_dns_manager_class_init (NMDnsManagerClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_CONFIGURATION] =
+ g_param_spec_variant (NM_DNS_MANAGER_CONFIGURATION, "", "",
+ G_VARIANT_TYPE ("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
signals[CONFIG_CHANGED] =
diff --git a/src/dns/nm-dns-manager.h b/src/dns/nm-dns-manager.h
index d8b253a69..2fc2031b7 100644
--- a/src/dns/nm-dns-manager.h
+++ b/src/dns/nm-dns-manager.h
@@ -54,6 +54,7 @@ typedef struct {
/* properties */
#define NM_DNS_MANAGER_MODE "mode"
#define NM_DNS_MANAGER_RC_MANAGER "rc-manager"
+#define NM_DNS_MANAGER_CONFIGURATION "configuration"
/* internal signals */
#define NM_DNS_MANAGER_CONFIG_CHANGED "config-changed"