core: read "disable_ipv6" sysctl before nm_ip6_config_create_setting()

First of all, the entire nm_device_generate_connection() and
nm_ip._config_create_setting() approach is fundamentally flawed. You
cannot generate sensible configuration by reading IP addresses from
an interface. Anyway, that's what we still sometimes do, and we possibly
should do it less and less.

It's ugly that nm_ip6_config_capture() would read the "disable_ipv6"
sysctl value and cache it in NMIP6Config. Only so that it can be use
much later during nm_ip6_config_create_setting().

Instead, read the sysctl value shortly before it's needed.
This commit is contained in:
Thomas Haller 2020-07-22 14:51:58 +02:00
parent b15c85cf8b
commit be655e6ed1
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 28 additions and 26 deletions

View file

@ -6169,6 +6169,26 @@ nm_device_master_update_slave_connection (NMDevice *self,
return FALSE;
}
static gboolean
_get_maybe_ipv6_disabled (NMDevice *self)
{
NMPlatform *platform;
int ifindex;
const char *path;
char ifname[IFNAMSIZ];
ifindex = nm_device_get_ip_ifindex (self);
if (ifindex <= 0)
return FALSE;
platform = nm_device_get_platform (self);
if (!nm_platform_if_indextoname (platform, ifindex, ifname))
return FALSE;
path = nm_sprintf_bufa (128, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
return (nm_platform_sysctl_get_int32 (platform, NMP_SYSCTL_PATHID_ABSOLUTE (path), 0) == 0);
}
NMConnection *
nm_device_generate_connection (NMDevice *self,
NMDevice *master,
@ -6237,7 +6257,7 @@ nm_device_generate_connection (NMDevice *self,
s_ip4 = nm_ip4_config_create_setting (priv->ip_config_4);
nm_connection_add_setting (connection, s_ip4);
s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6);
s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6, _get_maybe_ipv6_disabled (self));
nm_connection_add_setting (connection, s_ip6);
nm_connection_add_setting (connection, nm_setting_proxy_new ());
@ -13415,9 +13435,10 @@ nm_device_set_ip_config (NMDevice *self,
new_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection));
nm_connection_add_setting (new_connection,
IS_IPv4
? nm_ip4_config_create_setting (priv->ip_config_4)
: nm_ip6_config_create_setting (priv->ip_config_6));
IS_IPv4
? nm_ip4_config_create_setting (priv->ip_config_4)
: nm_ip6_config_create_setting (priv->ip_config_6,
_get_maybe_ipv6_disabled (self)));
nm_settings_connection_update (settings_connection,
new_connection,

View file

@ -64,7 +64,6 @@ typedef struct {
NMDedupMultiIdxType idx_ip6_routes;
};
NMIPConfigFlags config_flags;
bool ipv6_disabled;
} NMIP6ConfigPrivate;
struct _NMIP6Config {
@ -373,8 +372,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
const NMDedupMultiHeadEntry *head_entry;
NMDedupMultiIter iter;
const NMPObject *plobj = NULL;
char ifname[IFNAMSIZ];
char *path;
nm_assert (ifindex > 0);
@ -416,12 +413,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
nmp_cache_iter_for_each (&iter, head_entry, &plobj)
_add_route (self, plobj, NULL, NULL);
if (nm_platform_if_indextoname (platform, ifindex, ifname)) {
path = nm_sprintf_bufa (128, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
if (nm_platform_sysctl_get_int32 (platform, NMP_SYSCTL_PATHID_ABSOLUTE (path), 0) != 0)
priv->ipv6_disabled = TRUE;
}
return self;
}
@ -757,7 +748,7 @@ nm_ip6_config_merge_setting (NMIP6Config *self,
}
NMSetting *
nm_ip6_config_create_setting (const NMIP6Config *self)
nm_ip6_config_create_setting (const NMIP6Config *self, gboolean maybe_ipv6_disabled)
{
const NMIP6ConfigPrivate *priv;
NMSettingIPConfig *s_ip6;
@ -822,7 +813,7 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
/* Use 'ignore' if the method wasn't previously set */
if (!method) {
method = priv->ipv6_disabled
method = maybe_ipv6_disabled
? NM_SETTING_IP6_CONFIG_METHOD_DISABLED
: NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
}
@ -893,13 +884,11 @@ nm_ip6_config_merge (NMIP6Config *dst,
NMDedupMultiIter ipconf_iter;
const NMPlatformIP6Address *address = NULL;
const NMIP6ConfigPrivate *src_priv;
NMIP6ConfigPrivate *dst_priv;
g_return_if_fail (src != NULL);
g_return_if_fail (dst != NULL);
src_priv = NM_IP6_CONFIG_GET_PRIVATE (src);
dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst);
g_object_freeze_notify (G_OBJECT (dst));
@ -965,9 +954,6 @@ nm_ip6_config_merge (NMIP6Config *dst,
if (nm_ip6_config_get_dns_priority (src))
nm_ip6_config_set_dns_priority (dst, nm_ip6_config_get_dns_priority (src));
if (src_priv->ipv6_disabled)
dst_priv->ipv6_disabled = src_priv->ipv6_disabled;
g_object_thaw_notify (G_OBJECT (dst));
}
@ -1573,11 +1559,6 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
has_minor_changes = TRUE;
}
if (src_priv->ipv6_disabled != dst_priv->ipv6_disabled) {
dst_priv->ipv6_disabled = src_priv->ipv6_disabled;
has_minor_changes = TRUE;
}
#if NM_MORE_ASSERTS
/* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
* regardless of config_equal. But config_equal must correspond to has_relevant_changes. */

View file

@ -105,7 +105,7 @@ void nm_ip6_config_merge_setting (NMIP6Config *self,
NMSettingIPConfig *setting,
guint32 route_table,
guint32 route_metric);
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *self);
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *self, gboolean maybe_ipv6_disabled);
void nm_ip6_config_merge (NMIP6Config *dst,
const NMIP6Config *src,