Commit 25906eda authored by Ismo Puustinen's avatar Ismo Puustinen Committed by Thomas Haller

dns: add mechanism for propagating mDNS setting.

Update nm-policy.c and nm-dns-manager.c so that the connection-specific
settings get propagated to DNS manger. Currently the only such value is
the mDNS status.

Add update_mdns() function to DNS plugin interface. If a DNS plugin
supports mDNS, it can set an interface with a given index to support
mDNS resolving or also register the current hostname.

The mDNS support is currently added only to systemd-resolved DNS plugin.
parent 2e2ff6f2
This diff is collapsed.
......@@ -26,6 +26,7 @@
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
#include "nm-setting-connection.h"
typedef enum {
NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0,
......@@ -44,6 +45,12 @@ typedef struct {
char *iface;
} NMDnsIPConfigData;
typedef struct {
NMSettingConnectionMdns mdns;
char *iface;
int ifindex;
} NMDnsConnectionConfigData;
#define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ())
#define NM_DNS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DNS_MANAGER, NMDnsManager))
#define NM_DNS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_DNS_MANAGER, NMDnsManagerClass))
......@@ -82,6 +89,16 @@ void nm_dns_manager_set_initial_hostname (NMDnsManager *self,
void nm_dns_manager_set_hostname (NMDnsManager *self,
const char *hostname,
gboolean skip_update);
gboolean nm_dns_manager_add_connection_config (NMDnsManager *self,
const char *iface,
int ifindex,
NMSettingConnectionMdns mdns);
void nm_dns_manager_remove_connection_config (NMDnsManager *self,
const char *iface,
int ifindex);
void nm_dns_manager_update_ifindex (NMDnsManager *self,
const char *ip_iface,
int new_ifindex);
/**
* NMDnsManagerResolvConfManager
......
......@@ -89,6 +89,18 @@ nm_dns_plugin_update (NMDnsPlugin *self,
hostname);
}
gboolean
nm_dns_plugin_update_mdns (NMDnsPlugin *self,
int ifindex,
NMSettingConnectionMdns mdns)
{
g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update_mdns != NULL, FALSE);
return NM_DNS_PLUGIN_GET_CLASS (self)->update_mdns (self,
ifindex,
mdns);
}
static gboolean
is_caching (NMDnsPlugin *self)
{
......
......@@ -60,6 +60,11 @@ typedef struct {
*/
gboolean (*is_caching) (NMDnsPlugin *self);
/* Subclasses wishing to control interface mDNS status should override. */
gboolean (*update_mdns) (NMDnsPlugin *self,
int ifindex,
NMSettingConnectionMdns mdns);
/* Subclasses should override this and return their plugin name */
const char *(*get_name) (NMDnsPlugin *self);
......@@ -84,6 +89,10 @@ gboolean nm_dns_plugin_update (NMDnsPlugin *self,
const NMGlobalDnsConfig *global_config,
const char *hostname);
gboolean nm_dns_plugin_update_mdns (NMDnsPlugin *self,
int ifindex,
NMSettingConnectionMdns mdns);
void nm_dns_plugin_stop (NMDnsPlugin *self);
/* For subclasses/plugins */
......
......@@ -38,6 +38,7 @@
#include "nm-ip6-config.h"
#include "nm-bus-manager.h"
#include "nm-manager.h"
#include "nm-setting-connection.h"
#include "devices/nm-device.h"
#include "NetworkManagerUtils.h"
......@@ -57,6 +58,7 @@ typedef struct {
GDBusProxy *resolve;
GCancellable *init_cancellable;
GCancellable *update_cancellable;
GCancellable *mdns_cancellable;
GQueue dns_updates;
GQueue domain_updates;
} NMDnsSystemdResolvedPrivate;
......@@ -314,6 +316,45 @@ update (NMDnsPlugin *plugin,
return TRUE;
}
static gboolean
update_mdns (NMDnsPlugin *plugin, int ifindex, NMSettingConnectionMdns mdns)
{
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (plugin);
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
char *value;
_LOGI ("update_mdns: %i/%d", ifindex, mdns);
nm_clear_g_cancellable (&priv->mdns_cancellable);
if (!priv->resolve)
return FALSE;
priv->mdns_cancellable = g_cancellable_new ();
switch (mdns) {
case NM_SETTING_CONNECTION_MDNS_YES:
value = "yes";
break;
case NM_SETTING_CONNECTION_MDNS_NO:
value = "no";
break;
case NM_SETTING_CONNECTION_MDNS_RESOLVE:
value = "resolve";
break;
default:
/* reset to system default */
value = "";
}
g_dbus_proxy_call (priv->resolve, "SetLinkMulticastDNS",
g_variant_new ("(is)", ifindex, value),
G_DBUS_CALL_FLAGS_NONE,
-1, priv->mdns_cancellable, call_done, self);
return TRUE;
}
/*****************************************************************************/
static gboolean
......@@ -402,6 +443,7 @@ dispose (GObject *object)
g_clear_object (&priv->resolve);
nm_clear_g_cancellable (&priv->init_cancellable);
nm_clear_g_cancellable (&priv->update_cancellable);
nm_clear_g_cancellable (&priv->mdns_cancellable);
G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object);
}
......@@ -416,5 +458,6 @@ nm_dns_systemd_resolved_class_init (NMDnsSystemdResolvedClass *dns_class)
plugin_class->is_caching = is_caching;
plugin_class->update = update;
plugin_class->update_mdns = update_mdns;
plugin_class->get_name = get_name;
}
......@@ -1059,6 +1059,35 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
_notify (self, PROP_DEFAULT_IP6_DEVICE);
}
static void
add_connection_dns (NMPolicy *self, NMConnection *connection, const char *iface, int ifindex)
{
NMSettingConnection *s_con = NULL;
if (connection == NULL)
return;
s_con = nm_connection_get_setting_connection (connection);
if (s_con) {
NMSettingConnectionMdns mdns = nm_setting_connection_get_mdns (s_con);
if (mdns != NM_SETTING_CONNECTION_MDNS_UNKNOWN)
nm_dns_manager_add_connection_config (NM_POLICY_GET_PRIVATE (self)->dns_manager,
iface,
ifindex,
mdns);
}
}
static void
remove_connection_dns (NMPolicy *self, const char *iface, int ifindex)
{
nm_dns_manager_remove_connection_config (NM_POLICY_GET_PRIVATE (self)->dns_manager,
iface,
ifindex);
}
static void
update_ip_dns (NMPolicy *self, int addr_family)
{
......@@ -1794,6 +1823,9 @@ device_state_changed (NMDevice *device,
*/
nm_connection_clear_secrets (NM_CONNECTION (connection));
/* Add connection settings (currently link mDNS state) */
add_connection_dns (self, NM_CONNECTION (connection), ip_iface, nm_device_get_ip_ifindex (device));
}
/* Add device's new IPv4 and IPv6 configs to DNS */
......@@ -1848,8 +1880,12 @@ device_state_changed (NMDevice *device,
&& old_state == NM_DEVICE_STATE_UNAVAILABLE)
reset_autoconnect_all (self, device, FALSE);
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
if (old_state > NM_DEVICE_STATE_DISCONNECTED) {
update_routing_and_dns (self, FALSE);
/* Remove connection settings (currently link mDNS state) */
remove_connection_dns (self, ip_iface, nm_device_get_ip_ifindex (device));
}
/* Device is now available for auto-activation */
schedule_activate_check (self, device);
......@@ -1982,6 +2018,19 @@ device_autoconnect_changed (NMDevice *device,
schedule_activate_check (self, device);
}
static void
device_ifindex_changed (NMDevice *device,
GParamSpec *pspec,
gpointer user_data)
{
NMPolicyPrivate *priv = user_data;
const char *ip_iface = nm_device_get_ip_iface (device);
int ifindex = nm_device_get_ifindex (device);
/* update ifindex mapping in DNS manager */
nm_dns_manager_update_ifindex (priv->dns_manager, ip_iface, ifindex);
}
static void
device_recheck_auto_activate (NMDevice *device, gpointer user_data)
{
......@@ -2010,6 +2059,7 @@ devices_list_register (NMPolicy *self, NMDevice *device)
g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip6_config_changed, priv);
g_signal_connect (device, NM_DEVICE_IP6_PREFIX_DELEGATED, (GCallback) device_ip6_prefix_delegated, priv);
g_signal_connect (device, NM_DEVICE_IP6_SUBNET_NEEDED, (GCallback) device_ip6_subnet_needed, priv);
g_signal_connect (device, "notify::" NM_DEVICE_IFINDEX, (GCallback) device_ifindex_changed, priv);
g_signal_connect (device, "notify::" NM_DEVICE_AUTOCONNECT, (GCallback) device_autoconnect_changed, priv);
g_signal_connect (device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, (GCallback) device_recheck_auto_activate, priv);
}
......@@ -2063,6 +2113,7 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn)
NMIP4Config *ip4_config;
NMIP6Config *ip6_config;
const char *ip_iface;
NMConnection *connection;
nm_dns_manager_begin_updates (priv->dns_manager, __func__);
......@@ -2081,6 +2132,10 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn)
update_routing_and_dns (self, TRUE);
nm_dns_manager_end_updates (priv->dns_manager, __func__);
/* Make sure the connection settings are set */
connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (vpn));
add_connection_dns (self, connection, ip_iface, nm_vpn_connection_get_ip_ifindex (vpn, TRUE));
}
static void
......@@ -2107,6 +2162,10 @@ vpn_connection_deactivated (NMPolicy *self, NMVpnConnection *vpn)
update_routing_and_dns (self, TRUE);
nm_dns_manager_end_updates (priv->dns_manager, __func__);
remove_connection_dns(self,
nm_vpn_connection_get_ip_iface (vpn, TRUE),
nm_vpn_connection_get_ip_ifindex (vpn, TRUE));
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment