mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-29 03:20:11 +01:00
device: fix IPv6 DAD to re-check whether address really failed DAD
In device_ipx_changed() we remember the addresses for which it appears that DAD failed. Later, on an idle handler, we process them during queued_ip6_config_change(). Note that nm_plaform_ip6_address_sync() might very well decide to remove some or all addresses and re-add them immidiately later. It might do so, to get the address priority/ordering right. At that point, we already emit platform signals that the device disappeared, and track them in dad6_failed_addrs. Hence, later during queued_ip6_config_change() we must check again whether the address is really not there and not still doing DAD. Otherwise, we wrongly claim that DAD failed and remove the address, generate a new one, and the same issue might happen again.
This commit is contained in:
parent
ede4dd70f3
commit
6d8a636563
2 changed files with 27 additions and 3 deletions
|
|
@ -11529,6 +11529,7 @@ queued_ip6_config_change (gpointer user_data)
|
|||
NMDevicePrivate *priv;
|
||||
GSList *iter;
|
||||
gboolean need_ipv6ll = FALSE;
|
||||
NMPlatform *platform;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
|
||||
|
||||
|
|
@ -11555,11 +11556,24 @@ queued_ip6_config_change (gpointer user_data)
|
|||
} else
|
||||
update_ip_config (self, AF_INET6, FALSE);
|
||||
|
||||
if (priv->state < NM_DEVICE_STATE_DEACTIVATING
|
||||
&& nm_platform_link_get (nm_device_get_platform (self), priv->ifindex)) {
|
||||
if ( priv->state < NM_DEVICE_STATE_DEACTIVATING
|
||||
&& (platform = nm_device_get_platform (self))
|
||||
&& nm_platform_link_get (platform, priv->ifindex)) {
|
||||
/* Handle DAD failures */
|
||||
for (iter = priv->dad6_failed_addrs; iter; iter = iter->next) {
|
||||
const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS (iter->data);
|
||||
const NMPObject *obj = iter->data;
|
||||
const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS (obj);
|
||||
const NMPlatformIP6Address *addr2;
|
||||
|
||||
addr2 = NMP_OBJECT_CAST_IP6_ADDRESS (nm_platform_lookup_obj (platform,
|
||||
NMP_CACHE_ID_TYPE_OBJECT_TYPE,
|
||||
obj));
|
||||
if ( addr2
|
||||
&& ( NM_FLAGS_HAS (addr2->n_ifa_flags, IFA_F_SECONDARY)
|
||||
|| !NM_FLAGS_HAS (addr2->n_ifa_flags, IFA_F_DADFAILED))) {
|
||||
/* the address still/again exists and is not in DADFAILED state. Skip it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
_LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address",
|
||||
nm_platform_ip6_address_to_string (addr, NULL, 0));
|
||||
|
|
|
|||
|
|
@ -730,6 +730,16 @@ const NMDedupMultiEntry *nm_platform_lookup_entry (NMPlatform *platform,
|
|||
NMPCacheIdType cache_id_type,
|
||||
const NMPObject *obj);
|
||||
|
||||
static inline const NMPObject *
|
||||
nm_platform_lookup_obj (NMPlatform *platform,
|
||||
NMPCacheIdType cache_id_type,
|
||||
const NMPObject *obj)
|
||||
{
|
||||
return nm_dedup_multi_entry_get_obj (nm_platform_lookup_entry (platform,
|
||||
cache_id_type,
|
||||
obj));
|
||||
}
|
||||
|
||||
static inline const NMDedupMultiHeadEntry *
|
||||
nm_platform_lookup_obj_type (NMPlatform *platform,
|
||||
NMPObjectType obj_type)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue