Calling va_start() (with va_end()) in between seems to work and
is done by systemd and other code occasionally.
However, it's not clear that this really works on every architecture.
So just replace thise one instance with a different implementation
by passing the arguments as an array.
First, cb751012a2 mistakenly converted the
act_stage_context_step() in connect_ready() to connect_context_clear()
instead of connect_context_step(). This would cause the IP Type retry
logic to fail and no further types to be tried. It also throws
away the ctx->first_error and causes all errors that MM returns on the
connect attempt to be dropped on the floor.
Second, not all errors should cause an advance to the next IP Type,
since some errors aren't related to it. Specifically, MM_CORE_ERROR_RETRY
when using Simple.Connect() means that a timeout was reached
in the internal connect logic, not a modem or network error. In
that case, try the connect again with the same IP Type before advancing
to the next type.
Fixes: cb751012a2
Tested-by: Ladislav Michl <ladis@linux-mips.org>
Tested-by: Tore Anderson <tore@fud.no>
When we decide to add a new link, we alredy checked that no such link exists
(ignoring race conditions).
It is wrong to accept a EXITS failure when adding the link. There is no guarantee
that the existing link has all the same properties as the one we intend to add.
More importantly, this link was added externally outside of NetworkManager and it
should not be taken over.
Just treat EXISTS as a failure as any other.
NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST is a multi-flag value combining all
the hooks that compose a user-request. Add a special value that has no esplicit
meaning except that it ~is~ a user-request.
For update, don't delete first and add it again. Just do it
in one step.
For recheck, don't delete all connections first to add them
all anew. Instead, check what changes and only emit the changed
signal if there are any actual changes.
The rules were added to the list using g_slist_append() and then
applied one at time using "iptables --insert" which puts them at the
beginning of the chain, reversing the initial order.
Instead, list them in the desired order and use g_slist_prepend() to
achieve the same result. This has no functional changes.
nm_supplicant_manager_iface_get() would cache and reuse the supplicant
interface. But no ref-counting was in place so that the first user returning
the interface via nm_supplicant_manager_iface_release() would destroy the
instance for others.
This is broken for a very long time. Which shows that we hardly ever
have a cache-hit and usually create a new instance. So, instead of
letting nm_supplicant_manager_create_interface() check for existing
supplicant interface, always create a new instance. This also makes
sense, because we would expect that per ifname only one instance is
requested at a time. Also add an assertion that we don't return
multiple supplicant interface instances for the same ifname.
Drop nm_supplicant_manager_iface_release() in favor of requiring users
to unref the returned instance.
Also, use a GSList instead of a GHashTable for the cache.
Also, previously callers would pass @is_wireless to nm_supplicant_manager_iface_get(),
but the cache lookup did not consider that value. That doesn't matter
now as we always create a new instance.
https://bugzilla.redhat.com/show_bug.cgi?id=1298007
Add a new object which implements the logic for announcing IP
addresses and detecting duplicates using arping.
Based-on-patch-by: Jiří Klimeš <jklimes@redhat.com>
The function can now be called on unrealized devices before the
initial unmanaged flags are set and for those devices
nm_device_get_managed() will return TRUE. Since we only accept
states > UNMANAGED, return early when the condition is not met.
Fixes the following failed assertion:
carrier_changed: assertion 'priv->state >= NM_DEVICE_STATE_UNAVAILABLE' failed
https://bugzilla.gnome.org/show_bug.cgi?id=760844
The availability checks are called from places that don't assume the device
will be removed mid-air. Call the removal routine only when we're the very
last thing that's being done.
During nm_device_unrealize(), the connection might still
have some connections that only get removed later. We must
garbage collect unrealized devices when they loose their
available-connections, not during unrealize.
Fixes: 436ec5b8e3
Apply MTU and hop limit when managed or other flag is set as well. This wasn't
the case for the first RA and the previous commit made it slightly worse by
always ignoring it.
Fixes: ad2584c375
With DHCPv6 it might be quite some time (we may even time out) until we get all
the information to finish activation, but we already have the addresses and
routes.
With the final removal the reason of NOW_UNMANAGED causes the cleanup on the
device to be run, which downs the device:
#0 nm_platform_link_set_down (self=0x555555a29bb0, ifindex=1711) at platform/nm-platform.c:1111
#1 0x00005555555d6ccf in nm_device_take_down (self=self@entry=0x555555c07c70, block=block@entry=1) at devices/nm-device.c:8175
#2 0x00005555555df0c7 in _set_state_full (self=0x555555c07c70, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_NOW_UNMANAGED, quitting=quitting@entry=0) at devices/nm-device.c:9825
#3 0x00005555555dfa97 in nm_device_state_changed (self=<optimized out>, state=<optimized out>, reason=<optimized out>) at devices/nm-device.c:10084
#4 0x00005555555e472c in nm_device_set_unmanaged_flags (self=<optimized out>, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED)
at devices/nm-device.c:8745
#5 0x00005555555e54a9 in nm_device_set_unmanaged_quitting (self=<optimized out>) at devices/nm-device.c:8806
#6 0x000055555565b1aa in remove_device (manager=manager@entry=0x555555a4a2c0, device=0x555555c07c70, quitting=quitting@entry=1, allow_unmanage=allow_unmanage@entry=1) at nm-manager.c:833
#7 0x0000555555660b81 in nm_manager_stop (self=0x555555a4a2c0) at nm-manager.c:4389
#8 0x00005555555b3f9b in main (argc=1, argv=0x7fffffffdba8) at main.c:493
The function returns early when autoconnect is off, so there's no reason to
branch for that case below. The signal is only generated for autoconnect=true.
The idea of NMDevice:realize() was to
(1) update the device properties
(2) fail realization if some critical properties are missing
(1) is already done during nm_device_setup_start().
(2) was only implemented by NMDeviceVlan:realize(), but it
basically was just checking whether such a platform device exists.
Other implementations don't do that either and it opens up for a race
when the device gets deleted externally.
Extract a function update_properties() similar to other device
implementations. It reads the device specific data from platform
and raises property-changed notifications.
update_properties() is now called by realize_start_notify().
NMDeviceVlan:realize() -- which previously implemented something like
update_properties() -- now does nothing. Note that previously
realize() might have failed, but this is different from other device
implementations and it was unclear what a failure really meant.
Ok, it might fail because the link was not found in the platform cache.
But other implementations don't check that either, so why vlan? And
how to handle that properly anyway?
Therefore realize()'s implementation is no longer needed because
nm_device_realize() already calls realize_start_setup(), which
calls realize_start_notify() and update_properties().
update_connection() no longer refreshes the device properties.
Instead it only modifies the passed-in NMConnection. It's a bit
ugly that update_connection() uses both cached properties from
NMDeviceVlan (vlan_id) and platform properties (xgress maps).
Also, update_connection() doesn't return early on error but continues
trying to update the NMConnection. The reason is that update_connection()
cannot return a failure status.
The virtual function NMDevice:realize() is only called by
nm_device_realize() and immediately followed by nm_device_setup_start().
Devices already overwrite setup_start_notify() to update their properties.
No need to duplicate that in realize().