device: add global configuration default for ip6-privacy (use_tempaddr, RFC4941)
Support default value for setting 'ipv6.ip6-privacy' in
NetworkManager.conf.
If the global value is unset, preserve old behavior of looking into
/etc/sycctl.conf first. That behavior was introduced with commit
d376270bfe
, since we support ip6-privacy
setting.
If the global value is set to "unknown", add a new fallback
that instead reads the runtime value from
"/proc/sys/net/ipv6/conf/default/use_tempaddr"
This seems more sensible behavior because we fallback to sysctl,
but instead of looking at static files in /etc, read /proc.
But to preserve the old behavior, we only do that when a global
value is configured at all.
https://bugzilla.gnome.org/show_bug.cgi?id=721200
This commit is contained in:
@@ -508,9 +508,20 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
|
|||||||
* 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary
|
* 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary
|
||||||
* addresses).
|
* addresses).
|
||||||
*
|
*
|
||||||
* This per-connection value is ignored when setting
|
* This property can be configured with a default value in global configuration
|
||||||
* "net.ipv6.conf.default.use_tempaddr" in /etc/sysctl.conf or
|
* NetworkManager.conf.
|
||||||
* /lib/sysctl.d/sysctl.conf to either "0", "1", or "2".
|
*
|
||||||
|
* If the global configuration value "connection.ipv6.ip6-privacy"
|
||||||
|
* is not specified, the sysctl value "net.ipv6.conf.default.use_tempaddr" in /etc/sysctl.conf or
|
||||||
|
* /lib/sysctl.d/sysctl.conf is always checked first. If set to "0", "1", or "2", that
|
||||||
|
* value is always used and any per-connection setting is ignored. This behavior is kept for
|
||||||
|
* backward compatiblity.
|
||||||
|
*
|
||||||
|
* Otherwise this per-connection setting is honored next. Having a per-connection setting set
|
||||||
|
* to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy".
|
||||||
|
*
|
||||||
|
* If the global configuration is explicitly set to "-1", fallback to read
|
||||||
|
* "/proc/sys/net/ipv6/conf/default/use_tempaddr".
|
||||||
**/
|
**/
|
||||||
/* ---ifcfg-rh---
|
/* ---ifcfg-rh---
|
||||||
* property: ip6-privacy
|
* property: ip6-privacy
|
||||||
|
@@ -490,7 +490,6 @@ ipv6.ip6-privacy=1
|
|||||||
Note that also "wlan0" gets "ipv6.ip6-privacy=1", because although the section
|
Note that also "wlan0" gets "ipv6.ip6-privacy=1", because although the section
|
||||||
"[connection-wifi-wlan0]" matches the device, it does not contain that property
|
"[connection-wifi-wlan0]" matches the device, it does not contain that property
|
||||||
and the search continues.
|
and the search continues.
|
||||||
This is just an example, ipv6.ip6-privacy property is currently not overwritable.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -523,6 +522,15 @@ ipv6.ip6-privacy=1
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>ipv4.route-metric</varname></term>
|
<term><varname>ipv4.route-metric</varname></term>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ipv6.ip6-privacy</varname></term>
|
||||||
|
<listitem><para>If this value is unset, NetworkManager will always first check "/etc/sysctl.conf" and "/etc/sysctl.d/sysctl.conf" whether
|
||||||
|
they contain "net.ipv6.conf.default.use_tempaddr". This value is then preferred over any per-connection
|
||||||
|
setting. That step is omitted when setting the global configuration value <literal>ipv6.ip6-privacy</literal>
|
||||||
|
to any value. If <literal>ipv6.ip6-privacy</literal> is set but neither "0", "1", or "2", use the content of
|
||||||
|
"/proc/sys/net/ipv6/conf/default/use_tempaddr" as last fallback.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>ipv6.route-metric</varname></term>
|
<term><varname>ipv6.route-metric</varname></term>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@@ -4711,8 +4711,10 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
static NMSettingIP6ConfigPrivacy
|
static NMSettingIP6ConfigPrivacy
|
||||||
use_tempaddr_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
|
_ip6_privacy_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
|
||||||
{
|
{
|
||||||
switch (use_tempaddr) {
|
switch (use_tempaddr) {
|
||||||
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
|
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
|
||||||
@@ -4728,7 +4730,7 @@ use_tempaddr_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
|
|||||||
* /lib/sysctl.d/sysctl.conf
|
* /lib/sysctl.d/sysctl.conf
|
||||||
*/
|
*/
|
||||||
static NMSettingIP6ConfigPrivacy
|
static NMSettingIP6ConfigPrivacy
|
||||||
ip6_use_tempaddr (void)
|
_ip6_privacy_sysctl (void)
|
||||||
{
|
{
|
||||||
char *contents = NULL;
|
char *contents = NULL;
|
||||||
const char *group_name = "[forged_group]\n";
|
const char *group_name = "[forged_group]\n";
|
||||||
@@ -4752,7 +4754,7 @@ ip6_use_tempaddr (void)
|
|||||||
|
|
||||||
tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error);
|
tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error);
|
||||||
if (error == NULL)
|
if (error == NULL)
|
||||||
ret = use_tempaddr_clamp (tmp);
|
ret = _ip6_privacy_clamp (tmp);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
@@ -4763,6 +4765,74 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NMSettingIP6ConfigPrivacy
|
||||||
|
_ip6_privacy_get (NMDevice *self)
|
||||||
|
{
|
||||||
|
NMSettingIP6ConfigPrivacy ip6_privacy;
|
||||||
|
gs_free char *value = NULL;
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
||||||
|
|
||||||
|
value = nm_config_data_get_connection_default (nm_config_get_data (nm_config_get ()),
|
||||||
|
"ipv6.ip6-privacy", self);
|
||||||
|
|
||||||
|
/* 1.) If (and only if) the default value is not configured, check _ip6_privacy_sysctl()
|
||||||
|
* first. This is to preserve backward compatibility. In this case -- having no
|
||||||
|
* default value in global configuration, but use_tempaddr configured in /etc/sysctl --
|
||||||
|
* the per-connection setting is always ignored. */
|
||||||
|
if (!value) {
|
||||||
|
ip6_privacy = _ip6_privacy_sysctl ();
|
||||||
|
if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
|
||||||
|
return ip6_privacy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2.) Next we always look at the per-connection setting. If it is not -1 (unknown),
|
||||||
|
* use it. */
|
||||||
|
connection = nm_device_get_connection (self);
|
||||||
|
if (connection) {
|
||||||
|
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));
|
||||||
|
ip6_privacy = _ip6_privacy_clamp (ip6_privacy);
|
||||||
|
if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
|
||||||
|
return ip6_privacy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3.) All options (per-connection, global, sysctl) are unset/default.
|
||||||
|
* Return UNKNOWN. Skip step 5.) because that would be a change in behavior
|
||||||
|
* compared to older versions. */
|
||||||
|
if (!value)
|
||||||
|
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
||||||
|
|
||||||
|
/* 4.) use the default value from the configuration. */
|
||||||
|
ip6_privacy = _nm_utils_ascii_str_to_int64 (value, 10,
|
||||||
|
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
||||||
|
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
|
||||||
|
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
||||||
|
if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
|
||||||
|
return ip6_privacy;
|
||||||
|
|
||||||
|
/* 5.) A default-value is configured, but it is invalid/unknown. Fallback to sysctl reading.
|
||||||
|
*
|
||||||
|
* _ip6_privacy_sysctl() only reads two files from /etc and does not support the complexity
|
||||||
|
* of parsing all files. Also, it only considers "net.ipv6.conf.default.use_tempaddr",
|
||||||
|
* not the per-interface values. This is kinda unexpected, but we do it in 1.) to preserve
|
||||||
|
* old behavior.
|
||||||
|
*
|
||||||
|
* Now, the user actively configured a default value to "unknown" and we can introduce new
|
||||||
|
* behavior without changing old behavior (step 1.).
|
||||||
|
* Instead of reading static config files in /etc, just read the current sysctl value.
|
||||||
|
* This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves
|
||||||
|
* the "default" entry untouched. */
|
||||||
|
ip6_privacy = nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/default/use_tempaddr", NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
||||||
|
return _ip6_privacy_clamp (ip6_privacy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
ip6_requires_slaves (NMConnection *connection)
|
ip6_requires_slaves (NMConnection *connection)
|
||||||
{
|
{
|
||||||
@@ -4861,18 +4931,7 @@ act_stage3_ip6_config_start (NMDevice *self,
|
|||||||
/* Re-enable IPv6 on the interface */
|
/* Re-enable IPv6 on the interface */
|
||||||
set_disable_ipv6 (self, "0");
|
set_disable_ipv6 (self, "0");
|
||||||
|
|
||||||
/* Enable/disable IPv6 Privacy Extensions.
|
ip6_privacy = _ip6_privacy_get (self);
|
||||||
* 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));
|
|
||||||
}
|
|
||||||
ip6_privacy = use_tempaddr_clamp (ip6_privacy);
|
|
||||||
|
|
||||||
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
|
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
|
||||||
if (!addrconf6_start (self, ip6_privacy)) {
|
if (!addrconf6_start (self, ip6_privacy)) {
|
||||||
|
Reference in New Issue
Block a user