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
teamd first adds the link and only then listens on the bus therefore we race
with it. Let's watch for the bus presence even for the teamd devices we didn't
add for all their lifetime and recheck for assumed connections as we see them.
We don't want to start a teamd instance when there's an externally added team
interface. We just don't want to try to the daemon if it's not there (addressed
by a later commit).
This reverts commit a78386b6d1.
Conflicts:
src/devices/team/nm-device-team.c
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
If NM IPv6LL wasn't enabled then there is no need to bounce disable_ipv6
to tell the kernel to re-enable kernel IPv6LL, because kernel IPv6LL
is already enabled.
https://bugzilla.gnome.org/show_bug.cgi?id=740702
We want to export the IP configuration of interfaces when they have some, but
the kernel doesn't care if they are IFF_UP or not. Neither should NetworkManager,
so don't force devices IFF_UP just because we're assuming their IP config.
Externally created software devices would be managed/assumed immediately
upon creation, which includes setting them IFF_UP and possibly turning
on NM-managed IPv6LL.
With this commit, expected behavior for external software devices is:
1) created: unmanaged state, no further action
2) IP address added but !IFF_UP: connection assumed, but device is not set IFF_UP
3) slave attached but !IFF_UP: connection assumed, but master is not set IFF_UP
3) set IFF_UP: connection assumed (if any), if not -> DISCONNECTED
This branch ensures that external software devices are not set IFF_UP
by NetworkManager when they are discovered. It additionally ensures that
they are not set IFF_UP during connection assumption. They may be set
IFF_UP later through specific user action.
https://bugzilla.gnome.org/show_bug.cgi?id=725647https://bugzilla.redhat.com/show_bug.cgi?id=1030947
Error: CHECKED_RETURN (CWE-252): [#def20]
NetworkManager-0.9.11.0/src/devices/nm-device.c:5037: check_return: Calling "g_spawn_async" without checking return value (as is done elsewhere 12 out of 13 times).
When dhclient trieds to request a previous lease and the server NAKs that
lease, dhclient emits the EXPIRE state. dhcpcd has also been known to emit
the 'nak' state for the same reason.
(systemd's DHCP client code does not push a NAK up to NetworkManager, but
jumps to the REBOOT state instead, so it is unaffected by this issue.)
NetworkManager saw the expire during IP configuration and treated that as
full activation failure. The connection would be restarted, the same lease
requested, and the same NAK delivered, over and over. Before a lease is
acquired, there is (by definition) no lease to expire, so these events
should be ignored.
We do, however, still want to handle abnormal failures, which is why
this patch splits the EXPIRE case from the FAIL case and handles them
separately.
https://bugzilla.gnome.org/show_bug.cgi?id=739482
Broken by 25387cd1ff
When an activation request comes in via D-Bus for a slave, the
slave device's priv->master is set in stage1 in master_ready_cb().
Then nm_device_bring_up() is called on the slave, which triggers
link_changed_cb() and device_link_changed(). That then executes
this code:
if (priv->master)
nm_device_enslave_slave (priv->master, self, NULL);
which enslaves the slave, but due to the NULL will not configure
the slave.
This code was only meant to be run for externally triggered
master/slave changes.
NetworkManager[30304]: <info> (virbr0): bridge port virbr0-nic was detached
NetworkManager[30304]: (devices/nm-device.c:962):nm_device_release_one_slave: runtime check failed: (reason == NM_DEVICE_STATE_REASON_NONE)
NetworkManager[30304]: <info> (virbr0-nic): released from master virbr0
If the slave is removed, then the master is already cleaned up so NM
doesn't need to do anything. 5dd48f fixed that but forgot to update
the !configure case, causing the warning but no other problems.
Fixes: 5dd48f7527
When the device decides it needs re-auth during IP config and returns
to the NEED_AUTH state, make sure we clean up any half-done IP operations
since they will be re-started after auth is completed and the
IP_CONFIG state is re-entered.
https://bugzilla.gnome.org/show_bug.cgi?id=741342
If we didn't start IPv4 and IPv6, but they're allowed to fail, progress
the activation without failing it. Also, progress assumed connections to
check-ip with whatever configuration that is available.
https://bugzilla.redhat.com/show_bug.cgi?id=1141264
because either GSM or CDMA is present. It is checked just above.
Coverity:
Defect type: DEADCODE
src/devices/bluetooth/nm-device-bt.c:312: dead_error_line: Execution cannot reach this statement: "fallback_prefix = dcgettext...".
nm_device_removed() calls nm_device_release_one_slave() in order to
fix up NetworkManager's master/slave bookkeeping, but we don't want to
tell the kernel to actually unslave the device, since that would
happen automatically anyway if the device was really removed, and
shouldn't happen if the device is just being removed from NM's device
list.
(In particular, don't remove all libvirt-created virtual network
devices from virbr0 when NetworkManager exits.)
nm_device_get_hw_address() may return NULL and nm_platform_link_get_type may
return NM_LINK_TYPE_NONE. While it might be a good idea to check for such cases
at the init time it seems easier to just ignore it and prevent blowing up in
subsequent deactivation.
A quick test case:
# while :; do ip link add moo0 type veth peer moo1; ip link del moo0 ; done
Yields:
NetworkManager:ERROR:devices/nm-device-ethernet.c:268:constructor:
assertion failed: (link_type == NM_LINK_TYPE_ETHERNET ||
link_type == NM_LINK_TYPE_VETH)
nm_device_set_hw_addr: assertion 'addr != NULL' failed
https://bugzilla.gnome.org/show_bug.cgi?id=740992
For IPv4, iproute for example defaults to a metric of 0.
Hence, the name NM_PLATFORM_ROUTE_METRIC_DEFAULT was misleading.
Also add a NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4 define for completeness.
https://bugzilla.gnome.org/show_bug.cgi?id=740780
We recently changed default values for route metrics. Revise that
again and increase the space between the default values.
No strong reason to do this, but it seems better to have larger
gaps and make use of the available range.
For IPv4 addresses, the kernel automatically adds a route when
configuring an IP address. Unfortunately, there is no way to control
this behavior or to set the route metric.
Fix this, by adding our own route and removing the kernel provided
one.
Note that this adds a major change in that we no longer call
nm_ip4_config_commit() for assumed devices.
https://bugzilla.gnome.org/show_bug.cgi?id=723178
Signed-off-by: Thomas Haller <thaller@redhat.com>
We've previously been just watching for state changes into UNMANAGED state. No
state change is emitted upon removal of a device which is already unmanaged.
https://bugzilla.gnome.org/show_bug.cgi?id=737659
Before, we would only track a device in NMDefaultRouteManager
if it had a default route. Otherwise the entry for the device
was removed.
That was wrong, because having no entry meant that the interface
is assumed and hence we would not touch the interface. Instead we must
esplicitly track devices without default route to know when an interface
has no default route.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The previous commit made NM enforce the default route on interfaces for
which NM manages a default route.
For interfaces that are configured never-default, NM will now pick up
any externally configured default route, as if it was managed by NM.
This is important, because NMDefaultRouteManager needs a notion of which
is the best device. Without this change, it was agnostic to default routes
on managed, never-default interfaces.
Signed-off-by: Thomas Haller <thaller@redhat.com>
When calling update_default_route(), NMDefaultRouteManager will look at the
source, and determine whether it has a default route or not. For example
for device sources, this means calling nm_device_get_ip4_default_route().
If the source indicates that it has no default route, the effect of
calling update_default_route() is the same as calling
remove_default_route() (hence, remove() can be replaced by update()).
If the source however still indicates a default route, the behavior
would be different. This case would be an undesired inconsistancy,
because source and NMDefaultRouteManager would disagree of whether
the source has a default route.
Source must always properly indicate whether it has a default route
or not, hence this situation does not arise.
Hence it is always better to call update().
Signed-off-by: Thomas Haller <thaller@redhat.com>
Not invoking a callback when cancelling the operation is counter
intuitive.
Note that NMPolicy refs the device, cancelling the call would leave
the reference hanging. That was not an issue because the call was
never cancelled. But still the behavior of NMFirewallManager is
unexpected.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel does not terminate an ongoing IPv6LL address process when
the IPv6LL address generation mode is set to 'none' (indicating that
userspace wishes to handle IPv6LL). Next, NetworkManager does not
expose IPv6 addresses internally until they have completed DAD. This
means that the kernel may still be performing DAD for an IPv6LL
address when NetworkManager turns userspace IPv6LL on, and when
DAD is complete NetworkManager will finally pay attention to the
address. If the device is in the DISCONNECTED state, NetworkManager
will then generate and assume an IPv6LL-only connection on the device.
Unfortunately, that behavior happens if the following is true:
1) IPv6LL addressing takes a while (eg, dad_transmits is high or
the kernel takes a while for some reason)
2) the activated connection fails quickly (dhclient fails or some
other fatal error terminates the activation attempt)
3) the activated connection has ipv6.method=ignore
In this case, when the device was brought up and ipv6.method=ignore,
NetworkManager re-enabled kernel IPv6LL and reset the IPv6 sysctl
properties. The kernel then generated an IPv6LL address and began
DAD. dhclient failed quickly, and NM deactivated the device. NM
then turned off kernel IPv6LL when deactivating the device, but the
kernel does not terminate the ongoing DAD. Some time after the device
entered the DISCONNECTED state, the kernel finished DAD and that
allowed NetworkManager to internally see the address, which caused
NetworkManager to emit the 'recheck-assume' signal. This
generated a new IPv6LL-only connection which was then assumed.
Bouncing 'disable_ipv6' when re-enabling userspace IPv6LL during
device deactivation flushes the tentative kernel IPv6LL address,
thus preventing the address from being announced after userspace
IPv6LL is re-enabled. The other alternative is to expose
tentative addresses (eg those still doing DAD) in NMPlatform so
they would be flushed when the device deactivates, but that is a
larger & riskier set of changes.
Reproducer:
- ifconfig eth0 down
- prepare a DHCPv4 connection with ipv6.method=ignore
- set /proc/sys/net/ipv6/conf/all/dad_transmits to "15"
- ensure that DHCPv4 will fail (replace dhclient with a script
that exits after 2 seconds or something)
- run NetworkManager
- activate the DHCP connection and watch it immediately fail
- wait for the kernel to announce the IPv6LL address after DAD finishes
- watch NM "assume" the new IPv6LL connection
https://bugzilla.gnome.org/show_bug.cgi?id=740096