diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2022-09-06 17:13:58 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2022-10-26 10:08:53 +0200 |
commit | addb4e3a0c610b47ed4baa727310803a302a6ba2 (patch) | |
tree | 651530c8b745cdee738b074ea9b35872ab833b44 | |
parent | 15d55e5a6841abd7efad21d5a098abe1978a89fc (diff) | |
download | NetworkManager-addb4e3a0c610b47ed4baa727310803a302a6ba2.tar.gz |
device: generate a new AC6 address when DAD fails
For addresses that fail DAD we need to call nm_ndisc_dad_failed() to
generate a new address if addrgenmode is stable-privacy.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1046
-rw-r--r-- | src/core/devices/nm-device.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 48fe6cbbd4..a8624754a4 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -4135,18 +4135,30 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N /* Check if AC6 addresses completed DAD */ if (NM_FLAGS_ANY(notify_data->platform_change_on_idle.obj_type_flags, nmp_object_type_to_flags(NMP_OBJECT_TYPE_IP6_ADDRESS)) - && priv->ipac6_data.state == NM_DEVICE_IP_STATE_PENDING && priv->ipac6_data.l3cd - && nm_l3cfg_check_ready(l3cfg, - priv->ipac6_data.l3cd, - AF_INET6, - NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY, - NULL)) { - if (nm_l3cfg_has_temp_not_available_obj(priv->l3cfg, AF_INET6)) - _dev_l3_cfg_commit(self, FALSE); - - nm_clear_l3cd(&priv->ipac6_data.l3cd); - _dev_ipac6_set_state(self, NM_DEVICE_IP_STATE_READY); - _dev_ip_state_check_async(self, AF_INET6); + && priv->ipac6_data.state == NM_DEVICE_IP_STATE_PENDING && priv->ipac6_data.l3cd) { + gs_unref_array GArray *conflicts = NULL; + gboolean ready; + + ready = nm_l3cfg_check_ready(l3cfg, + priv->ipac6_data.l3cd, + AF_INET6, + NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY, + &conflicts); + if (conflicts) { + /* nm_ndisc_dad_failed() will emit a new "NDisc:config-received" + * signal; _dev_ipac6_ndisc_config_changed() will be called + * synchronously to update the current state and schedule a commit. */ + nm_ndisc_dad_failed(priv->ipac6_data.ndisc, conflicts, TRUE); + } else if (ready) { + if (nm_l3cfg_has_temp_not_available_obj(priv->l3cfg, AF_INET6)) + _dev_l3_cfg_commit(self, FALSE); + + nm_clear_l3cd(&priv->ipac6_data.l3cd); + _dev_ipac6_set_state(self, NM_DEVICE_IP_STATE_READY); + _dev_ip_state_check_async(self, AF_INET6); + } else { + /* wait */ + } } _dev_ipmanual_check_ready(self); @@ -11435,6 +11447,12 @@ _dev_ipac6_ndisc_config_changed(NMNDisc *ndisc, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); gboolean ready; + /* The ndisc configuration changes when we receive a new RA or + * when a lifetime expires; but also when DAD fails for a + * SLAAC address and we need to regenerate new stable-privacy + * addresses. In all these cases we update the AC6 configuration, + * schedule a commit and update the AC state. */ + _dev_ipac6_grace_period_start(self, 0, TRUE); _dev_l3_register_l3cds_set_one_full(self, |