Commit c03a5349 authored by Thomas Haller's avatar Thomas Haller

core: implement setting MDNS setting for systemd

The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.

However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.

We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.

Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).

Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
parent b40729ca
......@@ -654,6 +654,9 @@ ipv6.ip6-privacy=0
<varlistentry>
<term><varname>connection.lldp</varname></term>
</varlistentry>
<varlistentry>
<term><varname>connection.mdns</varname></term>
</varlistentry>
<varlistentry>
<term><varname>connection.stable-id</varname></term>
</varlistentry>
......
......@@ -1878,6 +1878,34 @@ out:
return nm_utils_ip_route_metric_normalize (addr_family, route_metric);
}
static NMSettingConnectionMdns
_get_mdns (NMDevice *self)
{
NMConnection *connection;
NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
g_return_val_if_fail (NM_IS_DEVICE (self), NM_SETTING_CONNECTION_MDNS_DEFAULT);
connection = nm_device_get_applied_connection (self);
if (connection)
mdns = nm_setting_connection_get_mdns (nm_connection_get_setting_connection (connection));
if (mdns == NM_SETTING_CONNECTION_MDNS_DEFAULT) {
gs_free char *value = NULL;
value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"connection.mdns",
self);
mdns = _nm_utils_ascii_str_to_int64 (value,
10,
NM_SETTING_CONNECTION_MDNS_NO,
NM_SETTING_CONNECTION_MDNS_YES,
NM_SETTING_CONNECTION_MDNS_DEFAULT);
}
return mdns;
}
guint32
nm_device_get_route_table (NMDevice *self,
int addr_family,
......@@ -5922,6 +5950,7 @@ ensure_con_ip4_config (NMDevice *self)
priv->con_ip4_config = _ip4_config_new (self);
nm_ip4_config_merge_setting (priv->con_ip4_config,
nm_connection_get_setting_ip4_config (connection),
_get_mdns (self),
nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET));
......@@ -6217,6 +6246,7 @@ dhcp4_state_changed (NMDhcpClient *client,
manual = _ip4_config_new (self);
nm_ip4_config_merge_setting (manual,
nm_connection_get_setting_ip4_config (connection),
NM_SETTING_CONNECTION_MDNS_DEFAULT,
nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET));
......@@ -6596,6 +6626,7 @@ act_stage3_ip4_config_start (NMDevice *self,
config = _ip4_config_new (self);
nm_ip4_config_merge_setting (config,
nm_connection_get_setting_ip4_config (connection),
NM_SETTING_CONNECTION_MDNS_DEFAULT,
nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET));
......@@ -9313,6 +9344,7 @@ nm_device_reactivate_ip4_config (NMDevice *self,
priv->con_ip4_config = _ip4_config_new (self);
nm_ip4_config_merge_setting (priv->con_ip4_config,
s_ip4_new,
_get_mdns (self),
nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET));
......
......@@ -24,6 +24,7 @@
#include <netinet/in.h>
#include "nm-setting-connection.h"
#include "nm-exported-object.h"
#include "nm-dbus-interface.h"
#include "nm-connection.h"
......
......@@ -228,6 +228,8 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic)
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
GVariantBuilder dns, domains;
NMCListElem *elem;
NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
const char *mdns_arg = NULL;
g_variant_builder_init (&dns, G_VARIANT_TYPE ("(ia(iay))"));
g_variant_builder_add (&dns, "i", ic->ifindex);
......@@ -237,18 +239,43 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic)
g_variant_builder_add (&domains, "i", ic->ifindex);
g_variant_builder_open (&domains, G_VARIANT_TYPE ("a(sb)"));
c_list_for_each_entry (elem, &ic->configs_lst_head, lst)
update_add_ip_config (self, &dns, &domains, elem->data);
c_list_for_each_entry (elem, &ic->configs_lst_head, lst) {
NMIPConfig *ip_config = elem->data;
update_add_ip_config (self, &dns, &domains, ip_config);
if (NM_IS_IP4_CONFIG (ip_config))
mdns = NM_MAX (mdns, nm_ip4_config_mdns_get (NM_IP4_CONFIG (ip_config)));
}
g_variant_builder_close (&dns);
g_variant_builder_close (&domains);
switch (mdns) {
case NM_SETTING_CONNECTION_MDNS_NO:
mdns_arg = "no";
break;
case NM_SETTING_CONNECTION_MDNS_RESOLVE:
mdns_arg = "resolve";
break;
case NM_SETTING_CONNECTION_MDNS_YES:
mdns_arg = "yes";
break;
case NM_SETTING_CONNECTION_MDNS_DEFAULT:
mdns_arg = "";
break;
}
nm_assert (mdns_arg);
_request_item_append (&priv->request_queue_lst_head,
"SetLinkDNS",
g_variant_builder_end (&dns));
_request_item_append (&priv->request_queue_lst_head,
"SetLinkDomains",
g_variant_builder_end (&domains));
_request_item_append (&priv->request_queue_lst_head,
"SetLinkMulticastDNS",
g_variant_new ("(is)", ic->ifindex, mdns_arg ?: ""));
}
static void
......
......@@ -293,6 +293,7 @@ typedef struct {
int ifindex;
NMIPConfigSource mtu_source;
gint dns_priority;
NMSettingConnectionMdns mdns;
GArray *nameservers;
GPtrArray *domains;
GPtrArray *searches;
......@@ -901,6 +902,7 @@ _nm_ip_config_merge_route_attributes (int addr_family,
void
nm_ip4_config_merge_setting (NMIP4Config *self,
NMSettingIPConfig *setting,
NMSettingConnectionMdns mdns,
guint32 route_table,
guint32 route_metric)
{
......@@ -1017,6 +1019,8 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
if (priority)
nm_ip4_config_set_dns_priority (self, priority);
nm_ip4_config_mdns_set (self, mdns);
g_object_thaw_notify (G_OBJECT (self));
}
......@@ -1232,6 +1236,11 @@ nm_ip4_config_merge (NMIP4Config *dst,
if (nm_ip4_config_get_dns_priority (src))
nm_ip4_config_set_dns_priority (dst, nm_ip4_config_get_dns_priority (src));
/* mdns */
nm_ip4_config_mdns_set (dst,
NM_MAX (nm_ip4_config_mdns_get (src),
nm_ip4_config_mdns_get (dst)));
g_object_thaw_notify (G_OBJECT (dst));
}
......@@ -1468,6 +1477,10 @@ nm_ip4_config_subtract (NMIP4Config *dst,
if (nm_ip4_config_get_dns_priority (src) == nm_ip4_config_get_dns_priority (dst))
nm_ip4_config_set_dns_priority (dst, 0);
/* mdns */
if (nm_ip4_config_mdns_get (src) == nm_ip4_config_mdns_get (dst))
nm_ip4_config_mdns_set (dst, NM_SETTING_CONNECTION_MDNS_DEFAULT);
g_object_thaw_notify (G_OBJECT (dst));
}
......@@ -1568,6 +1581,7 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst,
/* ignore dns options */
/* ignore NIS */
/* ignore WINS */
/* ignore mdns */
if (update_dst)
g_object_thaw_notify (G_OBJECT (dst));
......@@ -1846,6 +1860,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
has_relevant_changes = TRUE;
}
dst_priv->mdns = src_priv->mdns;
/* DNS priority */
if (src_priv->dns_priority != dst_priv->dns_priority) {
nm_ip4_config_set_dns_priority (dst, src_priv->dns_priority);
......@@ -2523,6 +2539,21 @@ nm_ip4_config_get_dns_option (const NMIP4Config *self, guint i)
/*****************************************************************************/
NMSettingConnectionMdns
nm_ip4_config_mdns_get (const NMIP4Config *self)
{
return NM_IP4_CONFIG_GET_PRIVATE (self)->mdns;
}
void
nm_ip4_config_mdns_set (NMIP4Config *self,
NMSettingConnectionMdns mdns)
{
NM_IP4_CONFIG_GET_PRIVATE (self)->mdns = mdns;
}
/*****************************************************************************/
void
nm_ip4_config_set_dns_priority (NMIP4Config *self, gint priority)
{
......@@ -3133,6 +3164,7 @@ nm_ip4_config_init (NMIP4Config *self)
nm_ip_config_dedup_multi_idx_type_init ((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
NMP_OBJECT_TYPE_IP4_ROUTE);
priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32));
priv->domains = g_ptr_array_new_with_free_func (g_free);
priv->searches = g_ptr_array_new_with_free_func (g_free);
......
......@@ -21,6 +21,8 @@
#ifndef __NETWORKMANAGER_IP4_CONFIG_H__
#define __NETWORKMANAGER_IP4_CONFIG_H__
#include "nm-setting-connection.h"
#include "nm-exported-object.h"
#include "nm-setting-ip4-config.h"
......@@ -172,6 +174,7 @@ gboolean nm_ip4_config_commit (const NMIP4Config *self,
void nm_ip4_config_merge_setting (NMIP4Config *self,
NMSettingIPConfig *setting,
NMSettingConnectionMdns mdns,
guint32 route_table,
guint32 route_metric);
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *self);
......@@ -198,6 +201,10 @@ const NMPObject *_nm_ip4_config_best_default_route_find (const NMIP4Config *self
in_addr_t nmtst_ip4_config_get_gateway (NMIP4Config *config);
NMSettingConnectionMdns nm_ip4_config_mdns_get (const NMIP4Config *self);
void nm_ip4_config_mdns_set (NMIP4Config *self,
NMSettingConnectionMdns mdns);
const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self);
void nm_ip4_config_reset_addresses (NMIP4Config *self);
void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address);
......
......@@ -1888,9 +1888,8 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) {
svSetValueEnum (ifcfg, "MDNS", nm_setting_connection_mdns_get_type (),
mdns);
} else {
} else
svUnsetValue (ifcfg, "MDNS");
}
}
static char *
......
......@@ -1460,6 +1460,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
NMPlatformIP4Address address;
guint32 u32, route_metric;
NMSettingIPConfig *s_ip;
NMSettingConnection *s_con;
guint32 route_table;
NMIP4Config *config;
GVariantIter *iter;
......@@ -1564,6 +1565,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
route_table = get_route_table (self, AF_INET, TRUE);
route_metric = nm_vpn_connection_get_ip4_route_metric (self);
s_ip = nm_connection_get_setting_ip4_config (_get_applied_connection (self));
s_con = nm_connection_get_setting_connection (_get_applied_connection (self));
if (nm_setting_ip_config_get_ignore_auto_routes (s_ip)) {
/* ignore VPN routes */
......@@ -1621,6 +1623,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
/* Merge in user overrides from the NMConnection's IPv4 setting */
nm_ip4_config_merge_setting (config,
s_ip,
nm_setting_connection_get_mdns (s_con),
route_table,
route_metric);
......
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