mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
l3cfg: set IPv6 sysctls during NML3Cfg commit
This commit is contained in:
parent
4b270448e4
commit
5c48c5d5d6
|
@ -1792,7 +1792,10 @@ nm_l3_config_data_set_ip6_mtu(NML3ConfigData *self, guint32 ip6_mtu)
|
|||
NMSettingIP6ConfigPrivacy
|
||||
nm_l3_config_data_get_ip6_privacy(const NML3ConfigData *self)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
nm_assert(!self || _NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
if (!self)
|
||||
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
||||
|
||||
return self->ip6_privacy;
|
||||
}
|
||||
|
@ -1894,7 +1897,7 @@ nm_l3_config_data_set_proxy_pac_script(NML3ConfigData *self, const char *value)
|
|||
gboolean
|
||||
nm_l3_config_data_get_ndisc_hop_limit(const NML3ConfigData *self, int *out_val)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
if (!self->ndisc_hop_limit_set) {
|
||||
NM_SET_OUT(out_val, 0);
|
||||
|
@ -1917,7 +1920,7 @@ nm_l3_config_data_set_ndisc_hop_limit(NML3ConfigData *self, int val)
|
|||
gboolean
|
||||
nm_l3_config_data_get_ndisc_reachable_time_msec(const NML3ConfigData *self, guint32 *out_val)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
if (!self->ndisc_reachable_time_msec_set) {
|
||||
NM_SET_OUT(out_val, 0);
|
||||
|
@ -1940,7 +1943,7 @@ nm_l3_config_data_set_ndisc_reachable_time_msec(NML3ConfigData *self, guint32 va
|
|||
gboolean
|
||||
nm_l3_config_data_get_ndisc_retrans_timer_msec(const NML3ConfigData *self, guint32 *out_val)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
if (!self->ndisc_retrans_timer_msec_set) {
|
||||
NM_SET_OUT(out_val, 0);
|
||||
|
@ -2230,7 +2233,7 @@ nm_l3_config_data_get_blacklisted_ip4_routes(const NML3ConfigData *self, gboolea
|
|||
const NMPObject * my_addr_obj;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
/* For IPv6 slaac, we explicitly add the device-routes (onlink).
|
||||
* As we don't do that for IPv4 and manual IPv6 addresses. Add them here
|
||||
|
|
|
@ -259,6 +259,25 @@ typedef struct _NML3CfgPrivate {
|
|||
|
||||
gint8 commit_reentrant_count;
|
||||
|
||||
/* The value that was set before we touched the sysctl (this only is
|
||||
* meaningful if "ip6_privacy_set" is true. At the end, we want to restore
|
||||
* this value. */
|
||||
NMSettingIP6ConfigPrivacy ip6_privacy_initial : 4;
|
||||
|
||||
/* The value that we set the last time. This is cached so that we don't
|
||||
* repeatedly try to commit the same value. */
|
||||
NMSettingIP6ConfigPrivacy ip6_privacy_set_before : 4;
|
||||
|
||||
guint32 ndisc_retrans_timer_msec;
|
||||
guint32 ndisc_reachable_time_msec;
|
||||
int ndisc_hop_limit;
|
||||
|
||||
/* Whether "self" set the ip6_privacy sysctl (and whether it needs to be reset). */
|
||||
bool ip6_privacy_set : 1;
|
||||
bool ndisc_reachable_time_msec_set : 1;
|
||||
bool ndisc_retrans_timer_msec_set : 1;
|
||||
bool ndisc_hop_limit_set : 1;
|
||||
|
||||
bool commit_type_update_sticky : 1;
|
||||
|
||||
bool acd_is_pending : 1;
|
||||
|
@ -3654,6 +3673,193 @@ out_prune:
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static const char *
|
||||
ip6_privacy_to_str(NMSettingIP6ConfigPrivacy ip6_privacy)
|
||||
{
|
||||
switch (ip6_privacy) {
|
||||
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
|
||||
return "0";
|
||||
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
|
||||
return "1";
|
||||
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
|
||||
return "2";
|
||||
case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
return nm_assert_unreachable_val("0");
|
||||
}
|
||||
|
||||
static void
|
||||
_l3_commit_ndisc_params(NML3Cfg *self, NML3CfgCommitType commit_type)
|
||||
{
|
||||
const NML3ConfigData *l3cd;
|
||||
gboolean retrans_set = FALSE;
|
||||
gboolean reachable_set = FALSE;
|
||||
gboolean hop_limit_set = FALSE;
|
||||
guint32 reachable;
|
||||
guint32 retrans;
|
||||
int hop_limit;
|
||||
const char * ifname;
|
||||
|
||||
if (commit_type < NM_L3_CFG_COMMIT_TYPE_UPDATE) {
|
||||
self->priv.p->ndisc_reachable_time_msec_set = FALSE;
|
||||
self->priv.p->ndisc_retrans_timer_msec_set = FALSE;
|
||||
self->priv.p->ndisc_hop_limit_set = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
l3cd = self->priv.p->combined_l3cd_commited;
|
||||
if (l3cd) {
|
||||
reachable_set = nm_l3_config_data_get_ndisc_reachable_time_msec(l3cd, &reachable);
|
||||
retrans_set = nm_l3_config_data_get_ndisc_retrans_timer_msec(l3cd, &retrans);
|
||||
hop_limit = nm_l3_config_data_get_ndisc_hop_limit(l3cd, &hop_limit);
|
||||
}
|
||||
ifname = nm_l3cfg_get_ifname(self, TRUE);
|
||||
|
||||
if (reachable_set
|
||||
&& (!self->priv.p->ndisc_reachable_time_msec_set
|
||||
|| self->priv.p->ndisc_reachable_time_msec != reachable)) {
|
||||
self->priv.p->ndisc_reachable_time_msec = reachable;
|
||||
self->priv.p->ndisc_reachable_time_msec_set = TRUE;
|
||||
if (ifname) {
|
||||
nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(self->priv.platform,
|
||||
ifname,
|
||||
reachable);
|
||||
}
|
||||
}
|
||||
|
||||
if (retrans_set
|
||||
&& (!self->priv.p->ndisc_retrans_timer_msec_set
|
||||
|| self->priv.p->ndisc_reachable_time_msec != retrans)) {
|
||||
self->priv.p->ndisc_retrans_timer_msec = retrans;
|
||||
self->priv.p->ndisc_retrans_timer_msec_set = TRUE;
|
||||
if (ifname) {
|
||||
nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(self->priv.platform, ifname, retrans);
|
||||
}
|
||||
}
|
||||
|
||||
if (hop_limit_set
|
||||
&& (!self->priv.p->ndisc_hop_limit_set || self->priv.p->ndisc_hop_limit != hop_limit)) {
|
||||
self->priv.p->ndisc_hop_limit = hop_limit;
|
||||
self->priv.p->ndisc_hop_limit_set = TRUE;
|
||||
if (ifname) {
|
||||
nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(self->priv.platform,
|
||||
ifname,
|
||||
hop_limit);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: restore values if necessary
|
||||
}
|
||||
|
||||
static void
|
||||
_l3_commit_ip6_privacy(NML3Cfg *self, NML3CfgCommitType commit_type)
|
||||
{
|
||||
NMSettingIP6ConfigPrivacy ip6_privacy;
|
||||
NMSettingIP6ConfigPrivacy ip6_privacy_set_before;
|
||||
const char * ifname;
|
||||
|
||||
if (commit_type < NM_L3_CFG_COMMIT_TYPE_UPDATE)
|
||||
ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
||||
else
|
||||
ip6_privacy = nm_l3_config_data_get_ip6_privacy(self->priv.p->combined_l3cd_commited);
|
||||
|
||||
if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) {
|
||||
if (!self->priv.p->ip6_privacy_set) {
|
||||
/* Nothing to set. But do we need to reset a previous value? */
|
||||
return;
|
||||
}
|
||||
self->priv.p->ip6_privacy_set = FALSE;
|
||||
ip6_privacy = self->priv.p->ip6_privacy_initial;
|
||||
ifname = nm_l3cfg_get_ifname(self, TRUE);
|
||||
_LOGT("commit-ip6-privacy: reset initial value %d (was %d)%s%s",
|
||||
(int) ip6_privacy,
|
||||
(int) self->priv.p->ip6_privacy_set_before,
|
||||
NM_PRINT_FMT_QUOTED2(ifname, ", ifname ", ifname, " (skip, no interface)"));
|
||||
if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
|
||||
return;
|
||||
if (!ifname)
|
||||
return;
|
||||
goto set;
|
||||
}
|
||||
|
||||
nm_assert(NM_IN_SET(ip6_privacy,
|
||||
NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED,
|
||||
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR,
|
||||
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR));
|
||||
|
||||
if (self->priv.p->ip6_privacy_set && self->priv.p->ip6_privacy_set_before == ip6_privacy
|
||||
&& commit_type < NM_L3_CFG_COMMIT_TYPE_REAPPLY) {
|
||||
/* Already set. We leave this alone except during reapply. */
|
||||
return;
|
||||
}
|
||||
|
||||
ip6_privacy_set_before = self->priv.p->ip6_privacy_set_before;
|
||||
self->priv.p->ip6_privacy_set_before = ip6_privacy;
|
||||
|
||||
if (!self->priv.p->ip6_privacy_set) {
|
||||
gint64 s = G_MININT64;
|
||||
|
||||
self->priv.p->ip6_privacy_set = TRUE;
|
||||
ifname = nm_l3cfg_get_ifname(self, TRUE);
|
||||
if (ifname) {
|
||||
s = nm_platform_sysctl_ip_conf_get_int_checked(self->priv.platform,
|
||||
AF_INET6,
|
||||
ifname,
|
||||
"use_tempaddr",
|
||||
10,
|
||||
G_MININT32,
|
||||
G_MAXINT32,
|
||||
G_MININT64);
|
||||
if (s != G_MININT64)
|
||||
s = NM_CLAMP(s, 0, 2);
|
||||
}
|
||||
switch (s) {
|
||||
case 0:
|
||||
self->priv.p->ip6_privacy_initial = NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED;
|
||||
break;
|
||||
case 1:
|
||||
self->priv.p->ip6_privacy_initial = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR;
|
||||
break;
|
||||
case 2:
|
||||
self->priv.p->ip6_privacy_initial = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR;
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached();
|
||||
/* fall-through */
|
||||
case G_MININT64:
|
||||
self->priv.p->ip6_privacy_initial = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
_LOGT("commit-ip6-privacy: set value %d (initial value was %d)%s%s",
|
||||
(int) ip6_privacy,
|
||||
(int) self->priv.p->ip6_privacy_initial,
|
||||
NM_PRINT_FMT_QUOTED2(ifname, ", ifname ", ifname, " (skip, no interface)"));
|
||||
if (!ifname)
|
||||
return;
|
||||
/* The first time, we always set the value, and don't skip it based on what we
|
||||
* read. */
|
||||
goto set;
|
||||
}
|
||||
|
||||
ifname = nm_l3cfg_get_ifname(self, TRUE);
|
||||
_LOGT("commit-ip6-privacy: set value %d (after %d, initial value was %d)%s%s",
|
||||
(int) ip6_privacy,
|
||||
(int) ip6_privacy_set_before,
|
||||
(int) self->priv.p->ip6_privacy_initial,
|
||||
NM_PRINT_FMT_QUOTED2(ifname, ", ifname ", ifname, " (skip, no interface)"));
|
||||
if (!ifname)
|
||||
return;
|
||||
|
||||
set:
|
||||
nm_assert(ifname);
|
||||
self->priv.p->ip6_privacy_set_before = ip6_privacy;
|
||||
nm_platform_sysctl_ip_conf_set(self->priv.platform,
|
||||
AF_INET6,
|
||||
ifname,
|
||||
"use_tempaddr",
|
||||
ip6_privacy_to_str(ip6_privacy));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_l3_commit_one(NML3Cfg * self,
|
||||
|
@ -3709,6 +3915,11 @@ _l3_commit_one(NML3Cfg * self,
|
|||
addr_family);
|
||||
}
|
||||
|
||||
if (!IS_IPv4) {
|
||||
_l3_commit_ip6_privacy(self, commit_type);
|
||||
_l3_commit_ndisc_params(self, commit_type);
|
||||
}
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_NONE)
|
||||
route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_ALL;
|
||||
|
||||
|
@ -3725,9 +3936,7 @@ _l3_commit_one(NML3Cfg * self,
|
|||
} else
|
||||
_obj_state_zombie_lst_get_prune_lists(self, addr_family, &addresses_prune, &routes_prune);
|
||||
|
||||
/* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ip6_privacy(). */
|
||||
/* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ndisc_*(). */
|
||||
/* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_ip6_mtu(). */
|
||||
/* FIXME(l3cfg): need to honor and set nm_l3_config_data_get_mtu(). */
|
||||
|
||||
nm_platform_ip_address_sync(self->priv.platform,
|
||||
|
|
Loading…
Reference in a new issue