The connection now might be being activated on another device. Defer the
removal until we're sure the activation request will proceed and only add the
active connection afterwards.
https://bugzilla.gnome.org/show_bug.cgi?id=730492
Since f85513b (device: do not touch sysctls after the device was removed) the
device is not unconfigured/cleaned up when it's removed. When we're quitting
the device is not actually removed, we're just unmanaging it -- let's just
use a different reason so that the cleanup runs.
Fixes: f85513b8e4
Some device types (s390 OSA and ipvlan) can use the same link-layer address
for multiple virtual interfaces, and the kernel used the dev_id property
to differentiate these devices when constructing the IID. NM should do
this too to prevent IID clashes.
https://bugzilla.redhat.com/show_bug.cgi?id=1101809
Configuration commit is an unsafe thing to do for assumed connections,
it can remove an externally added address we don't know about yet.
The device already has a link-local address; for an assumed connection
it's the reason we assumed the method=link-local in the first place.
Paths to sysctls don't use ifindex and device names can be reused. If someone
removes a device and quickly creates a device with the same name, chances are
we're cleaning up the device that was just added.
Sadly, it seems there's no better API than sysctl-- neither netlink nor procfs
symlinks with ifindex or anything like that.
It would subtract the configuration from device confguration that's not yet
applied. This a the race where the loose the address while activating a
connection that has both IPv6 and IPv4 configuration.
Fixes: 557667df12https://bugzilla.gnome.org/show_bug.cgi?id=746066
These functions will sometimes get called on updates to the device's IP
config due to external changes, or when addresses get flushed from the
device when activating it. If the device is a slave device, then at
this point its NMConnection won't have an IP settings. Suppress the
warning that gets printed when s_ip == NULL, because it's expected.
Just a refactoring, doesn't make any actual difference. It is consistent with
IPv4 and will make it easier to implement a policy to recover from incorrect
MTUs settings.
No functional change, a cosmetic thing for now.
We want it set before any routes are added and ensure routes have a valid
ifindex before we pass it to the platform.
In a future NMRouteManager will need to look up the route for a device in
its cache thus we'll need to make sure routes passed to the it have an
appropriate ifindex set.
No functional change, a cosmetic thing for now.
We want it set before any routes are added and ensure routes have a valid
ifindex before we pass it to the platform.
In a future NMRouteManager will need to look up the route for a device in
its cache thus we'll need to make sure routes passed to the it have an
appropriate ifindex set.
Create a NMRouteManager singleton.
Refactor, no functional changes apart from change of log domain from
LOGD_PLATFORM to LOGD_CORE.
Subsequent commit will keep track of the conflicting routes, avoid overwriting
older ones with newer ones and apply the new ones when the old ones go away.
It's always user requested -- auto activation never happens on already active
devices. nm_device_release_one_slave() rightly asserts teardown with
(un)configuration does not happen for no reason at all.
https://bugzilla.gnome.org/show_bug.cgi?id=744812
It was confusing to understand the difference between calling nm_device_connection_is_available()
and check_connection_available(), they behaved similar, but not really
the same. Especially nm_device_connection_is_available() would look
first into @available_connetions, and might call check_connection_available()
itself. Whereas @available_connetions was also populated by testing
check_connection_available(). This interrelation makes it hard to
understand when nm_device_connection_is_available() returned true.
Rename nm_device_connection_is_available() to nm_device_check_connection_available()
and remove all direct calls of check_connection_available() in favor of
the wrapper nm_device_check_connection_available().
Now we only call nm_device_check_connection_available() with different
parameters (@flags and @specific_object). We also have the additional
guarantee that specifying more @flags will widen the result and making
a connection "more" available, while specifying a @specific_object will
restrict it.
This also changes behavior in several cases. For example before
nm_device_connection_is_available() for user-requests would always
declare matching connections available on Wi-Fi devices (only)
regardless of the device state. Now the device state gets consistently
considered.
For default-unmanaged devices it also changes behavior in complicated
ways, because before we would put connections into @available_connetions
for every device-state, but nm_device_connection_is_available() had a
special over-ride only for unmanaged-state.
This also fixes a bug, that user can activate an unavailable Wi-Fi
device:
nmcli radio wifi off
nmcli connection up wlan0
The argument name should express what the caller wants
(he wants to know, whether the connection can be activated
for an internal or external activation request).
Whether that involves checking device-specific overrides, is
not the point -- nm_device_check_connection_compatible() is
also a virtual function with device-specific overrides.
Extend nm_match_spec_*() to support an "except:" prefix to negate
the result of a match. "except:" only works when followed by
an exact match type, for example "except:interface-name:vboxnet0",
but not "except:vboxnet0".
A matching "except:" spec always wins, regardless of other positive
matchings.
NMTestDevice does not invoke dispose(), hence it leaks memory which causes
false warnings in testing.
Some minor refactring to let dispose() clear the fields, but free it
later in finalize(). This avoids memleaks in the NMTestDevice stub.
During queued_ip_config_change(), we eventually call update_ip_config()
and ip4_config_merge_and_apply(). These functions read the IP configuration
from platform and setup the private ip4_config instance.
Trigger this initialization after constructing the device to setup
the IP configuration.
Before, for unmanaged devices we would not call ip4_config_merge_and_apply()
until the first platform change event.
Note that in the worst case we do some unnecessary work due to this,
because queued_ip_config_change() must already be robust to be called
at any time.
We trigger a new solicitation upon seeing the new token. Kernel triggers one
too, but that one is of no use to us, since the advertisement might arrive sooner
than we learn about the token change.
Even more eagerly pickup external default routes from the device.
For assumed devices we already picked up the default route.
(a) For assumed devices we already did not enforce the default route at all.
Instead it was always picked up by from the actualy system
configuration. Note that this is the case for assumed-generated
connections and for assuming existing connections.
That means that when NM assumes a connection at startup, it will never
actively manage the default route on that interface. It will only react
on what is present.
(b) For managed devices that have by configuration no default route, still pick up
the default route. That means, that even a device that is managed and
never-default=yes, can have the default route -- if configured externally.
(c) Only during a commit phase (i.e. when we have new configuraiton to be
applied), we enforce the default route or its absence.
(d) During any IP change event from platform, we again pickup whatever
is present. That means if you remove the default route from a managed
interface, NM will not re-add it until anything triggers (c).
This also means, that during the commit phase, we add default routes as
'synced' to the default-route-manager, but the following event from platform,
will change the route entry immediately to 'non-synced'. That is
expected and correct.
When receiving IP changes via platform event, remove all missing
addresses and routes from our internal configurations (such as
wwan, vpn, dhcp).
The effect is that on the next commit, those addresses and routes will
not be re-added as they were explicitly removed by the user.
However on a new DHCP lease or similar events, the addresses will
be added anew.
Another important improvement is that the NMIPxConfig of the active
device reflects when addresses or routes get removed externally. Before
we would continue to expose those entires although they were not
actually configured on the device.
https://bugzilla.gnome.org/show_bug.cgi?id=740443
In the IPv4 case, we check whether we have a direct route to the gateway
also by looking at the configured addresses/subnets. That is correct,
because every IPv4 address also implies a subnet route.
For IPv6, we explicitly add all subnet routes manually (noprefixroute),
hence, we have a direct route exactly if we have it in our list.
Regardless of the configured IPv6 prefixes.
We forgot to include the BRIDGE, so that bridge
devices got a default priority (route-metric) of 950
Add it between VLAN and MODEM type.
Also return a different metric for UNKNOWN
device types, but these priorities are not
actually expected.
Add nm_utils_setpgid() as a g_spawn*() child setup function for
calling setpgid(), and use it where appropriate rather than
reimplementing it every time.
There's no point in calling setpgid() on short-lived processes, so
remove the setpgid() calls when spawning dispatcher scripts, iptables,
iscsiadmin, and netconf.
Replace the pthread_sigwait()-based signal handling with
g_unix_signal_add()-based handling, and get rid of all the
now-unnecessary calls to nm_unblock_posix_signals() when spawning
subprocesses.
As a bonus, this also fixes the "^C in gdb kills NM too" bug.
If a device assumes a connection without activating a user-requested or
NM-requested connection, then disable_ipv6 is not touched. When the device
is deactivated, it still isn't touched even though userspace IPv6LL
is enabled. This could lead to an user-requested activation with
IPv6 configuration, but disable_ipv6=1.
Whenever userspace IPv6LL is turned on, we should also set disable_ipv6=0
to ensure IPv6 can function. Userspace IPv6LL will ensure that the
interface does not have an address until the user/connection requests
it, which was the only reason that NM touched disable_ipv6 anyway.
fixes:NetworkManager_Test203_testcase_286589
fixes:NetworkManager_Test204_testcase_286590
https://bugzilla.gnome.org/show_bug.cgi?id=741773
When userspace IPv6LL capability is compiled into NetworkManager,
during deactivation NM will toggle userspace IPv6LL in some cases.
This causes link change events in the platform, which show up
in nm-device.c::device_link_changed().
When an EXTERNAL_DOWN interface was activated, the EXTERNAL_DOWN
flag was never cleared even if the device was set IFF_UP or if
a connection was activated via D-Bus (which explicitly sets the
device up).
Second, the device_link_changed() code changed device state
whether or not IFF_UP had actually changed, it simply looked at
the current value.
Together, this caused the first activation of an EXTERNAL_DOWN
device to succeed, but the EXTERNAL_DOWN flag was never cleared
even though the activation set the device IFF_UP. When a second
activation request came in, the device was moved to DISCONNECTED
state and IPv6LL genmode was reset, causing device_link_changed()
to run. Since the device had EXTERNAL_DOWN and IFF_UP were still
set, nm_device_set_unmanaged_flag() code was triggered to clear
EXTERNAL_DOWN, which resulted in a state transition to UNAVAILABLE
with a reason of CONNECTION_ASSUMED. This caused the second
activation request to fail because UNAVAILABLE devices cannot
activate connections by definition.
The fix has three parts:
1) Only change EXTERNAL_DOWN if IFF_UP actually changes, to prevent
spurious changes when something other than IFF_UP changes
2) Only clear EXTERNAL_DOWN when IFF_UP changes while the device
is UNMANAGED, since any state higher than UNMANAGED implies that
either an activation request was received (and thus the device
should be managed) or IFF_UP was set
3) Clear EXTERNAL_DOWN (without triggering state changes) when
any state higher than UNAVAILABLE is entered, since this implies
that a connection is activating or the device is no longer
IFF_UP
fixes:NetworkManager_Test108_testcase_303655
https://bugzilla.gnome.org/show_bug.cgi?id=741742
#0 0x00007f6c3aed34e9 in g_logv (log_domain=0x7f6c3ea7341c "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff0a33fb60) at gmessages.c:989
#1 0x00007f6c3aed363f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007f6c3e8ead4f in nm_device_get_iface (self=0x0) at devices/nm-device.c:502
#3 0x00007f6c3e904f59 in nm_device_slave_notify_release (self=0x7f6c3fb48e60, reason=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:1618
#4 0x00007f6c3e8ed69f in nm_device_release_one_slave (self=0x7f6c3fb22670, slave=0x7f6c3fb48e60, configure=1, reason=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:968
#5 0x00007f6c3e904bf7 in slave_state_changed (slave=0x7f6c3fb48e60, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=NM_DEVICE_STATE_REASON_REMOVED, self=0x7f6c3fb22670)
at devices/nm-device.c:1368
#6 0x00007f6c39829d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#7 0x00007f6c398296bc in ffi_call (cif=cif@entry=0x7fff0a340070, fn=0x7f6c3e9049d0 <slave_state_changed>, rvalue=0x7fff0a33ffe0, avalue=avalue@entry=0x7fff0a33ff60) at ../src/x86/ffi64.c:522
#8 0x00007f6c3b1bfad8 in g_cclosure_marshal_generic (closure=0x7f6c3fb5c8c0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#9 0x00007f6c3b1bf298 in g_closure_invoke (closure=0x7f6c3fb5c8c0, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff0a340270, invocation_hint=invocation_hint@entry=0x7fff0a340210)
at gclosure.c:777
#10 0x00007f6c3b1d135d in signal_emit_unlocked_R (node=node@entry=0x7f6c3faf5d10, detail=detail@entry=0, instance=instance@entry=0x7f6c3fb48e60, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff0a340270) at gsignal.c:3586
#11 0x00007f6c3b1d90f2 in g_signal_emit_valist (instance=instance@entry=0x7f6c3fb48e60, signal_id=signal_id@entry=64, detail=detail@entry=0, var_args=var_args@entry=0x7fff0a3404a8) at gsignal.c:3330
#12 0x00007f6c3b1d98f8 in g_signal_emit_by_name (instance=0x7f6c3fb48e60, detailed_signal=0x7f6c3ea70f83 "state-changed") at gsignal.c:3426
#13 0x00007f6c3e8f894f in _set_state_full (self=0x7f6c3fb48e60, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:7486
#14 0x00007f6c3e8f0706 in nm_device_state_changed (self=0x7f6c3fb48e60, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:7623
#15 0x00007f6c3e8f808b in nm_device_set_unmanaged (self=0x7f6c3fb48e60, flag=NM_UNMANAGED_INTERNAL, unmanaged=1, reason=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6652
#16 0x00007f6c3e9943d0 in remove_device (manager=0x7f6c3fb20150, device=0x7f6c3fb48e60, quitting=0, allow_unmanage=1) at nm-manager.c:752
#17 0x00007f6c3e995c29 in platform_link_cb (platform=0x7f6c3fa7a870, ifindex=73, plink=0x7fff0a341260, change_type=NM_PLATFORM_SIGNAL_REMOVED, reason=NM_PLATFORM_REASON_EXTERNAL, user_data=0x7f6c3fb20150) at nm-manager.c:2182
#18 0x00007f6c39829d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#19 0x00007f6c398296bc in ffi_call (cif=cif@entry=0x7fff0a340bc0, fn=0x7f6c3e995b60 <platform_link_cb>, rvalue=0x7fff0a340b30, avalue=avalue@entry=0x7fff0a340ab0) at ../src/x86/ffi64.c:522
#20 0x00007f6c3b1bfad8 in g_cclosure_marshal_generic (closure=0x7f6c3fb14cf0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#21 0x00007f6c3b1bf298 in g_closure_invoke (closure=0x7f6c3fb14cf0, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff0a340dc0, invocation_hint=invocation_hint@entry=0x7fff0a340d60)
at gclosure.c:777
#22 0x00007f6c3b1d135d in signal_emit_unlocked_R (node=node@entry=0x7f6c3fa76f00, detail=detail@entry=0, instance=instance@entry=0x7f6c3fa7a870, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff0a340dc0) at gsignal.c:3586
#23 0x00007f6c3b1d90f2 in g_signal_emit_valist (instance=instance@entry=0x7f6c3fa7a870, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff0a341018) at gsignal.c:3330
#24 0x00007f6c3b1d98f8 in g_signal_emit_by_name (instance=0x7f6c3fa7a870, detailed_signal=0x7f6c3ea5f1fa "link-changed") at gsignal.c:3426
#25 0x00007f6c3e92412a in announce_object (platform=0x7f6c3fa7a870, object=0x7f6c3fbb6fd0, change_type=NM_PLATFORM_SIGNAL_REMOVED, reason=NM_PLATFORM_REASON_EXTERNAL) at platform/nm-linux-platform.c:1625
#26 0x00007f6c3e92b0f9 in event_notification (msg=0x7f6c3fa946f0, user_data=0x7f6c3fa7a870) at platform/nm-linux-platform.c:1986
#27 0x00007f6c3c35812f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#28 recvmsgs (cb=0x7f6c3fa7a620, sk=0x7f6c3fa7a710) at nl.c:952
#29 nl_recvmsgs_report (sk=0x7f6c3fa7a710, cb=0x7f6c3fa7a620) at nl.c:1003
#30 0x00007f6c3c3584f9 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#31 0x00007f6c3e929dca in event_handler (channel=0x7f6c3fa78810, io_condition=G_IO_IN, user_data=0x7f6c3fa7a870) at platform/nm-linux-platform.c:4127
#32 0x00007f6c3aecc2a6 in g_main_dispatch (context=0x7f6c3fa68490) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0x7f6c3fa68490) at gmain.c:3642
#34 0x00007f6c3aecc628 in g_main_context_iterate (context=0x7f6c3fa68490, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x00007f6c3aecca3a in g_main_loop_run (loop=0x7f6c3fa68550) at gmain.c:3907
#36 0x00007f6c3e8e9fff in main (argc=1, argv=0x7fff0a341c88) at main.c:483
https://bugzilla.gnome.org/show_bug.cgi?id=741651