summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-04-16 16:38:00 +0200
committerThomas Haller <thaller@redhat.com>2015-05-14 17:04:07 +0200
commit5782b678748ef589a22fdd57ab13f27d8cc74180 (patch)
treef28bfc28d1d51d4badd486b6bf3040ebb7439441
parent502f324227ef8f7d67f3a918a1e6bf2ff934d982 (diff)
downloadNetworkManager-th/default-ip6-privacy-bgo721200-v1.tar.gz
device: add global configuration default for ip6-privacy (use_tempaddr, RFC4941)th/default-ip6-privacy-bgo721200-v1
Add configuration option default-setting-ipv6.ip6-privacy to NetworkManager.conf. https://bugzilla.gnome.org/show_bug.cgi?id=721200
-rw-r--r--libnm-core/nm-setting-ip6-config.c13
-rw-r--r--man/NetworkManager.conf.xml.in45
-rw-r--r--src/devices/nm-device.c68
-rw-r--r--src/nm-config-data.c108
-rw-r--r--src/nm-config-data.h2
5 files changed, 144 insertions, 92 deletions
diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c
index cc3aedf3d4..78d6caa55c 100644
--- a/libnm-core/nm-setting-ip6-config.c
+++ b/libnm-core/nm-setting-ip6-config.c
@@ -508,11 +508,14 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
* 1: enabled (prefer public address), 2: enabled (prefer temporary
* addresses).
*
- * This per-connection value is ignored when setting
- * "net.ipv6.conf.default.use_tempaddr" in /etc/sysctl.conf or
- * /lib/sysctl.d/sysctl.conf.
- * If set to -1 (default), the global configuration value main.ip6-privacy
- * is used.
+ * If set to -1 (default), the global configuration value
+ * "default-setting-ipv6.ip6-privacy" is used.
+ *
+ * If the global configuration value "default-setting-ipv6.ip6-privacy"
+ * is unset but "net.ipv6.conf.default.use_tempaddr" in /etc/sysctl.conf or
+ * /lib/sysctl.d/sysctl.conf is configured to "0", "1", or "2", that value
+ * from sysctl takes precedence. In that case a per-connection setting is
+ * always ignored.
**/
/* ---ifcfg-rh---
* property: ip6-privacy
diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in
index 37fc319a97..2545175bd0 100644
--- a/man/NetworkManager.conf.xml.in
+++ b/man/NetworkManager.conf.xml.in
@@ -286,21 +286,7 @@ no-auto-default=*
</listitem>
</varlistentry>
- <varlistentry>
- <term><varname>ip6-privacy</varname></term>
- <listitem><para>Set the global IPv6 privacy address configuration (RFC4941).
- If <literal>net.ipv6.conf.default.use_tempaddr</literal> is configured in
- <literal>/etc/sysctl.conf</literal> or <literal>/lib/sysctl.d/sysctl.conf</literal>,
- that value always takes precedence. Next, the privacy setting can be configured
- per-connection via ipv6.ip6-privacy. Only if the per-connection value is -1 (unknown),
- this global configuration is considered.
-
- Supported values are numeric values -1 (unknown, default), 0 (disabled), 1 (enabled,
- prefer public address), 2 (enabled, prefer temporary address).
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ </variablelist>
</refsect1>
<refsect1>
@@ -493,6 +479,35 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
</refsect1>
<refsect1>
+ <title><literal>default-setting-ipv6</literal> section</title>
+ <para>Default configuration values for the ipv6 setting of connections.</para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><varname>ip6-privacy</varname></term>
+ <listitem><para>The IPv6 connection setting <literal>ip6-privacy</literal>
+ determines the IPv6 Privacy Extensions for SLAAC, described in RFC4941 (use_tempaddr).
+ Valid values are -1 (unknown), 0 (disabled), 1 (enabled, prefer public address),
+ and 2 (enabled, prefer temporary address). The default value is
+ -1 which effectively is the same as disabled.
+ This global configuration value is used for connections that have their
+ 'ipv6.ip6-privacy' value -1 (unknown).
+ Note that if this global configuration option is not set, NM will first
+ check <literal>/etc/sysctl.conf</literal> and <literal>/lib/sysctl.d/sysctl.conf</literal>.
+ If the sysctl value "net.ipv6.conf.default.use_tempaddr" is configured to
+ either 0, 1, or 2, that value always takes precedence. In other words, if you
+ configure "use_tempaddr" in sysctl.conf, that value is used over the
+ per-connection setting. To ignore a configuration value in sysctl.conf and
+ instead honor the per-connection setting, you must set this global configuration
+ option.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
<title>Plugins</title>
<variablelist>
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 75ad956a9e..453ebb0963 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -4624,58 +4624,6 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable)
}
}
-static NMSettingIP6ConfigPrivacy
-use_tempaddr_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
-{
- switch (use_tempaddr) {
- case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
- case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
- case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
- return use_tempaddr;
- default:
- return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
- }
-}
-
-/* Get net.ipv6.conf.default.use_tempaddr value from /etc/sysctl.conf or
- * /lib/sysctl.d/sysctl.conf
- */
-static NMSettingIP6ConfigPrivacy
-ip6_use_tempaddr (void)
-{
- char *contents = NULL;
- const char *group_name = "[forged_group]\n";
- char *sysctl_data = NULL;
- GKeyFile *keyfile;
- GError *error = NULL;
- gint tmp;
- NMSettingIP6ConfigPrivacy ret = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
-
- /* Read file contents to a string. */
- if (!g_file_get_contents ("/etc/sysctl.conf", &contents, NULL, NULL))
- if (!g_file_get_contents ("/lib/sysctl.d/sysctl.conf", &contents, NULL, NULL))
- return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
-
- /* Prepend a group so that we can use GKeyFile parser. */
- sysctl_data = g_strdup_printf ("%s%s", group_name, contents);
-
- keyfile = g_key_file_new ();
- if (!g_key_file_load_from_data (keyfile, sysctl_data, -1, G_KEY_FILE_NONE, NULL))
- goto done;
-
- tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error);
- if (error == NULL)
- ret = use_tempaddr_clamp (tmp);
-
-done:
- g_free (contents);
- g_free (sysctl_data);
- g_clear_error (&error);
- g_key_file_free (keyfile);
-
- return ret;
-}
-
static gboolean
ip6_requires_slaves (NMConnection *connection)
{
@@ -4774,20 +4722,8 @@ act_stage3_ip6_config_start (NMDevice *self,
/* Re-enable IPv6 on the interface */
set_disable_ipv6 (self, "0");
- /* Enable/disable IPv6 Privacy Extensions.
- * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf),
- * use that value instead of per-connection value.
- */
- ip6_privacy = ip6_use_tempaddr ();
- if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) {
- NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
-
- if (s_ip6)
- ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6));
- if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
- ip6_privacy = nm_config_data_get_ip6_privacy (nm_config_get_data (nm_config_get ()));
- }
- ip6_privacy = use_tempaddr_clamp (ip6_privacy);
+ ip6_privacy = nm_config_data_get_ip6_privacy_for_connection (nm_config_get_data (nm_config_get ()),
+ connection, TRUE);
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
if (!addrconf6_start (self, ip6_privacy)) {
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 3fe006f0a7..0479cad584 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -50,7 +50,9 @@ typedef struct {
char *dns_mode;
char *rc_manager;
- NMSettingIP6ConfigPrivacy ip6_privacy;
+ struct {
+ NMSettingIP6ConfigPrivacy ip6_privacy;
+ } default_setting_ipv6;
} NMConfigDataPrivate;
@@ -162,12 +164,105 @@ nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device)
return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier);
}
+/************************************************************************/
+
+static NMSettingIP6ConfigPrivacy
+_ip6_privacy_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
+{
+ switch (use_tempaddr) {
+ case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
+ case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
+ case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
+ return use_tempaddr;
+ default:
+ return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+ }
+}
+
+/* Get net.ipv6.conf.default.use_tempaddr value from /etc/sysctl.conf or
+ * /lib/sysctl.d/sysctl.conf
+ */
+static NMSettingIP6ConfigPrivacy
+_ip6_privacy_sysctl (void)
+{
+ char *contents = NULL;
+ const char *group_name = "[forged_group]\n";
+ char *sysctl_data = NULL;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gint tmp;
+ NMSettingIP6ConfigPrivacy ret = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+
+ /* Read file contents to a string. */
+ if (!g_file_get_contents ("/etc/sysctl.conf", &contents, NULL, NULL))
+ if (!g_file_get_contents ("/lib/sysctl.d/sysctl.conf", &contents, NULL, NULL))
+ return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+
+ /* Prepend a group so that we can use GKeyFile parser. */
+ sysctl_data = g_strdup_printf ("%s%s", group_name, contents);
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_data (keyfile, sysctl_data, -1, G_KEY_FILE_NONE, NULL))
+ goto done;
+
+ tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error);
+ if (error == NULL)
+ ret = _ip6_privacy_clamp (tmp);
+
+done:
+ g_free (contents);
+ g_free (sysctl_data);
+ g_clear_error (&error);
+ g_key_file_free (keyfile);
+
+ return ret;
+}
+
+#define NM_SETTING_IP6_CONFIG_PRIVACY_SYSCTL ((NMSettingIP6ConfigPrivacy) -5)
+
NMSettingIP6ConfigPrivacy
-nm_config_data_get_ip6_privacy (const NMConfigData *self)
+nm_config_data_get_ip6_privacy_for_connection (const NMConfigData *self, NMConnection *connection, gboolean prefer_sysctl)
{
+ NMConfigDataPrivate *priv;
+ NMSettingIP6ConfigPrivacy ret;
+
g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
- return NM_CONFIG_DATA_GET_PRIVATE (self)->ip6_privacy;
+ priv = NM_CONFIG_DATA_GET_PRIVATE (self);
+
+ /* - if the global default value is unset, we first consult
+ * sysctl (if @prefer_sysctl). Hence, if you don't specify
+ * default_setting_ipv6.ip6_privacy, but sysctl.conf, sysctl.conf
+ * always wins over any per-connection setting. This is backward
+ * compatible to previous behavior.
+ * - if you configure any value for default_setting_ipv6.ip6_privacy, or
+ * don't configure sysctl.conf, we first always honor the per connection
+ * setting. IOW, if you configure any value for default_setting_ipv6.ip6_privacy,
+ * sysctl is ignored.
+ * - if no per-connection setting is present, fallback to default value
+ * from global configuration. */
+
+ ret = priv->default_setting_ipv6.ip6_privacy;
+ if (ret == NM_SETTING_IP6_CONFIG_PRIVACY_SYSCTL) {
+ /* the global value is "unknown. That means, consult sysctl first. */
+ if (prefer_sysctl) {
+ ret = _ip6_privacy_sysctl ();
+ if (ret != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
+ return ret;
+ } else
+ ret = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+ }
+ if (connection) {
+ NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
+
+ if (s_ip6) {
+ ret = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6));
+ ret = _ip6_privacy_clamp (ret);
+ if (ret != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
+ return ret;
+ }
+ }
+ return ret;
}
/************************************************************************/
@@ -368,8 +463,11 @@ constructed (GObject *object)
priv->ignore_carrier = nm_config_get_device_match_spec (priv->keyfile, "main", "ignore-carrier");
- tmp = g_key_file_get_value (priv->keyfile, "main", "ip6-privacy", NULL);
- priv->ip6_privacy = _nm_utils_ascii_str_to_int64 (tmp, 10, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
+ tmp = g_key_file_get_value (priv->keyfile, "default-setting-ipv6", "ip6-privacy", NULL);
+ priv->default_setting_ipv6.ip6_privacy = _nm_utils_ascii_str_to_int64 (tmp, 10,
+ NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
+ NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
+ NM_SETTING_IP6_CONFIG_PRIVACY_SYSCTL);
g_free (tmp);
G_OBJECT_CLASS (nm_config_data_parent_class)->constructed (object);
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index 8e6f90475b..36655ea7b1 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -95,7 +95,7 @@ const char *nm_config_data_get_rc_manager (const NMConfigData *self);
gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device);
-NMSettingIP6ConfigPrivacy nm_config_data_get_ip6_privacy (const NMConfigData *self);
+NMSettingIP6ConfigPrivacy nm_config_data_get_ip6_privacy_for_connection (const NMConfigData *self, NMConnection *connection, gboolean prefer_sysctl);
G_END_DECLS