|
|
|
@@ -280,11 +280,6 @@ typedef struct _NMDevicePrivate {
|
|
|
|
|
|
|
|
|
|
bool real:1;
|
|
|
|
|
|
|
|
|
|
/* there was a IP config change, but no idle action was scheduled because device
|
|
|
|
|
* is still not platform-init */
|
|
|
|
|
bool queued_ip4_config_pending:1;
|
|
|
|
|
bool queued_ip6_config_pending:1;
|
|
|
|
|
|
|
|
|
|
bool update_ip_config_completed_v4:1;
|
|
|
|
|
bool update_ip_config_completed_v6:1;
|
|
|
|
|
|
|
|
|
@@ -4104,9 +4099,6 @@ realize_start_setup (NMDevice *self,
|
|
|
|
|
_notify (self, PROP_UDI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
priv->queued_ip4_config_pending = TRUE;
|
|
|
|
|
priv->queued_ip6_config_pending = TRUE;
|
|
|
|
|
|
|
|
|
|
nm_device_update_hw_address (self);
|
|
|
|
|
nm_device_update_initial_hw_address (self);
|
|
|
|
|
nm_device_update_permanent_hw_address (self, FALSE);
|
|
|
|
@@ -10263,13 +10255,13 @@ _cleanup_ip_pre (NMDevice *self, int addr_family, CleanupType cleanup_type)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IS_IPv4) {
|
|
|
|
|
priv->queued_ip4_config_pending = FALSE;
|
|
|
|
|
dhcp4_cleanup (self, cleanup_type, FALSE);
|
|
|
|
|
arp_cleanup (self);
|
|
|
|
|
dnsmasq_cleanup (self);
|
|
|
|
|
ipv4ll_cleanup (self);
|
|
|
|
|
} else {
|
|
|
|
|
priv->queued_ip6_config_pending = FALSE;
|
|
|
|
|
g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
|
|
|
|
|
priv->dad6_failed_addrs = NULL;
|
|
|
|
|
g_clear_object (&priv->dad6_ip6_config);
|
|
|
|
|
dhcp6_cleanup (self, cleanup_type, FALSE);
|
|
|
|
|
nm_clear_g_source (&priv->linklocal6_timeout_id);
|
|
|
|
@@ -12270,22 +12262,16 @@ static gboolean
|
|
|
|
|
queued_ip_config_change (NMDevice *self, int addr_family)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
gboolean need_ipv6ll = FALSE;
|
|
|
|
|
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
|
|
|
|
NMPlatform *platform;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
nm_assert (IS_IPv4 ? !priv->queued_ip4_config_pending : !priv->queued_ip6_config_pending);
|
|
|
|
|
|
|
|
|
|
/* Wait for any queued state changes */
|
|
|
|
|
if (priv->queued_state.id)
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
|
|
|
|
|
|
priv->queued_ip_config_id_x[IS_IPv4] = 0;
|
|
|
|
|
|
|
|
|
|
/* If a commit is scheduled, this function would potentially interfere with
|
|
|
|
|
* it changing IP configurations before they are applied. Postpone the
|
|
|
|
|
* update in such case.
|
|
|
|
@@ -12294,38 +12280,38 @@ queued_ip_config_change (NMDevice *self, int addr_family)
|
|
|
|
|
IS_IPv4
|
|
|
|
|
? activate_stage5_ip4_config_result
|
|
|
|
|
: activate_stage5_ip6_config_commit,
|
|
|
|
|
addr_family)) {
|
|
|
|
|
if (IS_IPv4) {
|
|
|
|
|
priv->queued_ip4_config_pending = FALSE;
|
|
|
|
|
priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self);
|
|
|
|
|
} else {
|
|
|
|
|
priv->queued_ip6_config_pending = FALSE;
|
|
|
|
|
priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self);
|
|
|
|
|
}
|
|
|
|
|
_LOGT (LOGD_DEVICE, "IP%c update was postponed",
|
|
|
|
|
nm_utils_addr_family_to_char (addr_family));
|
|
|
|
|
} else {
|
|
|
|
|
update_ip_config (self, addr_family);
|
|
|
|
|
addr_family))
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
/* Check whether we need to complete waiting for link-local.
|
|
|
|
|
* We are also called from an idle handler, so no problem doing state transitions
|
|
|
|
|
* now. */
|
|
|
|
|
linklocal6_check_complete (self);
|
|
|
|
|
}
|
|
|
|
|
priv->queued_ip_config_id_x[IS_IPv4] = 0;
|
|
|
|
|
|
|
|
|
|
update_ip_config (self, addr_family);
|
|
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
/* Check whether we need to complete waiting for link-local.
|
|
|
|
|
* We are also called from an idle handler, so no problem doing state transitions
|
|
|
|
|
* now. */
|
|
|
|
|
linklocal6_check_complete (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
if ( priv->state < NM_DEVICE_STATE_DEACTIVATING
|
|
|
|
|
NMPlatform *platform;
|
|
|
|
|
GSList *dad6_failed_addrs, *iter;
|
|
|
|
|
|
|
|
|
|
dad6_failed_addrs = g_steal_pointer (&priv->dad6_failed_addrs);
|
|
|
|
|
|
|
|
|
|
if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
|
|
|
|
|
&& priv->state < NM_DEVICE_STATE_DEACTIVATING
|
|
|
|
|
&& !nm_device_sys_iface_state_is_external (self)
|
|
|
|
|
&& (platform = nm_device_get_platform (self))
|
|
|
|
|
&& nm_platform_link_get (platform, priv->ifindex)) {
|
|
|
|
|
/* Handle DAD failures */
|
|
|
|
|
while (priv->dad6_failed_addrs) {
|
|
|
|
|
nm_auto_nmpobj const NMPObject *obj = NULL;
|
|
|
|
|
const NMPlatformIP6Address *addr;
|
|
|
|
|
gboolean need_ipv6ll = FALSE;
|
|
|
|
|
NMNDiscConfigMap ndisc_config_changed = NM_NDISC_CONFIG_NONE;
|
|
|
|
|
|
|
|
|
|
obj = priv->dad6_failed_addrs->data;
|
|
|
|
|
priv->dad6_failed_addrs = g_slist_delete_link (priv->dad6_failed_addrs, priv->dad6_failed_addrs);
|
|
|
|
|
/* Handle DAD failures */
|
|
|
|
|
for (iter = dad6_failed_addrs; iter; iter = iter->next) {
|
|
|
|
|
const NMPObject *obj = iter->data;
|
|
|
|
|
const NMPlatformIP6Address *addr;
|
|
|
|
|
|
|
|
|
|
if (!nm_ndisc_dad_addr_is_fail_candidate (platform, obj))
|
|
|
|
|
continue;
|
|
|
|
@@ -12338,9 +12324,12 @@ queued_ip_config_change (NMDevice *self, int addr_family)
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL (&addr->address))
|
|
|
|
|
need_ipv6ll = TRUE;
|
|
|
|
|
else if (priv->ndisc)
|
|
|
|
|
nm_ndisc_dad_failed (priv->ndisc, &addr->address);
|
|
|
|
|
ndisc_config_changed |= nm_ndisc_dad_failed (priv->ndisc, &addr->address, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ndisc_config_changed != NM_NDISC_CONFIG_NONE)
|
|
|
|
|
nm_ndisc_emit_config_change (priv->ndisc, ndisc_config_changed);
|
|
|
|
|
|
|
|
|
|
/* If no IPv6 link-local address exists but other addresses do then we
|
|
|
|
|
* must add the LL address to remain conformant with RFC 3513 chapter 2.1
|
|
|
|
|
* ("Addressing Model"): "All interfaces are required to have at least
|
|
|
|
@@ -12349,14 +12338,14 @@ queued_ip_config_change (NMDevice *self, int addr_family)
|
|
|
|
|
if ( priv->ip_config_6
|
|
|
|
|
&& nm_ip6_config_get_num_addresses (priv->ip_config_6))
|
|
|
|
|
need_ipv6ll = TRUE;
|
|
|
|
|
|
|
|
|
|
if (need_ipv6ll)
|
|
|
|
|
check_and_add_ipv6ll_addr (self);
|
|
|
|
|
} else {
|
|
|
|
|
g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
|
|
|
|
|
priv->dad6_failed_addrs = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slist_free_full (dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
/* Check if DAD is still pending */
|
|
|
|
|
if ( priv->ip6_state == IP_CONF
|
|
|
|
|
&& priv->dad6_ip6_config
|
|
|
|
@@ -12412,16 +12401,20 @@ device_ipx_changed (NMPlatform *platform,
|
|
|
|
|
if (nm_device_get_ip_ifindex (self) != ifindex)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!nm_device_is_real (self))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
|
|
|
|
/* ignore all platform signals until the link is initialized in platform. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
switch (obj_type) {
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
|
|
|
|
priv->queued_ip4_config_pending = TRUE;
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4));
|
|
|
|
|
} else if (!priv->queued_ip_config_id_4) {
|
|
|
|
|
priv->queued_ip4_config_pending = FALSE;
|
|
|
|
|
if (!priv->queued_ip_config_id_4) {
|
|
|
|
|
priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self);
|
|
|
|
|
_LOGD (LOGD_DEVICE, "queued IP4 config change");
|
|
|
|
|
}
|
|
|
|
@@ -12435,13 +12428,10 @@ device_ipx_changed (NMPlatform *platform,
|
|
|
|
|
priv->dad6_failed_addrs = g_slist_prepend (priv->dad6_failed_addrs,
|
|
|
|
|
(gpointer) nmp_object_ref (NMP_OBJECT_UP_CAST (addr)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
|
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
|
|
|
|
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
|
|
|
|
priv->queued_ip6_config_pending = TRUE;
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6));
|
|
|
|
|
} else if (!priv->queued_ip_config_id_6) {
|
|
|
|
|
priv->queued_ip6_config_pending = FALSE;
|
|
|
|
|
if (!priv->queued_ip_config_id_6) {
|
|
|
|
|
priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self);
|
|
|
|
|
_LOGD (LOGD_DEVICE, "queued IP6 config change");
|
|
|
|
|
}
|
|
|
|
@@ -12708,17 +12698,11 @@ _set_unmanaged_flags (NMDevice *self,
|
|
|
|
|
!!unmanaged);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->queued_ip4_config_pending) {
|
|
|
|
|
priv->queued_ip4_config_pending = FALSE;
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4));
|
|
|
|
|
priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->queued_ip6_config_pending) {
|
|
|
|
|
priv->queued_ip6_config_pending = FALSE;
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6));
|
|
|
|
|
priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self);
|
|
|
|
|
}
|
|
|
|
|
/* trigger an initial update of IP configuration. */
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4));
|
|
|
|
|
nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6));
|
|
|
|
|
priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self);
|
|
|
|
|
priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self);
|
|
|
|
|
|
|
|
|
|
if (!priv->pending_actions) {
|
|
|
|
|
do_notify_has_pending_actions = TRUE;
|
|
|
|
|