We would not expect that delayed_action_handle_all() is called recursively.
Assert against that. If we ever happen to call it recursively, we would
need to take care of properly avoiding infinite loops or deep call
stacks.
Track pending netlink requests and properly report the resulting errno
back.
Currently we send only requests in do_request_link() and do_request_all().
These callers don't actually care about the result, all they care that the
request is answered before returning back from platform code to the caller.
Thus, up to now the tracking of the sequence number was pretty simple.
Later we also want to get the errno from a request, thus rework sending
requests to also remember about outstanding sequence numbers and
properly track muliple parallel requests.
Later the synchronous actions (e.g. add-link) will also be handled
via the asynchronous socket.
Calling nl_recvmsgs_default() leads dirctly to recvmsgs() from
"nl.c". This functions reads messages (recvmsg) in a loop and
invokes the callbacks.
Later we want to merge nlh and nlh_event, meaning that we must
anticipate parsing unrelated messages while waiting for an ACK.
While that would be possible by registering different callbacks
and letting them interact, it is actually more complicated. Just
assume full control over the message parsing.
Basically, copy recvmsgs() to event_handler_recvmsg(). For now just
copy the function and do little adjustment (to show the similarity
to the original). Cleanup follows.
The nm_device_master_add_slave() also modifies slave's master property which
impacts the ability to enslave. When called in reaction to external
master property change we now no longer call enslave_slave which used to queue
the recheck previously:
# nmcli c add type bridge ifname br0
# ip link add dummy0 type dummy
# ip link set dummy0 up
# ip link set dummy0 master br0 # We should recheck for assumed connection
# here, since dummy0 can now be assumed.
We only need to do that when we're replacing the master with a different
one. Just after the link creation is has no master and we'd remove it
from the master device here.
Randomly choosing one between the two link creation methods (platform
and external) makes it more difficult to immediately detect when a bug
in introduced. Always execute them using both methods to have a better
code coverage, but still try a third time with a random one to test
different combinations of methods.
Fixes a crash if we can't read the ATM index. We need the ATM
index, and we can't do anything with the device before we have it,
so don't bother creating one if we we can't get it.
NetworkManager[9662]: <error> [1449678770.705541] [nm-device-adsl.c:607] constructor(): (atmtcp0): error reading ATM device index
(NetworkManager:9662): GLib-GObject-CRITICAL **: object NMDeviceAdsl 0x1e8f880 finalized while still in-construction
(NetworkManager:9662): GLib-GObject-CRITICAL **: Custom constructor for class NMDeviceAdsl returned NULL (which is invalid). Please use GInitable instead.
**
NetworkManager-adsl:ERROR:nm-atm-manager.c:121:adsl_add: assertion failed: (device)
At some point the platform changed to no longer ask the kernel for
interfaces when one wasn't in its cache, but to wait for netlink
events to be notified of the new interface. That broke some assumptions
that the ADSL code was making, causing a crash.
Rework the ADSL br2684 interface to clean up a couple of things
(get rid of 'disposed', consolidate dispose/deactivate cleanup) and
watch for the br2684 interface to show up with a periodic timeout.
Only do so on user initiated changes. Fixes this:
# ip link add br0 type bridge
# ip addr add 2001:DB8::666/64 dev br0
# ip link set br0 up # A generated connection is assumed
# ip link del br0 # The device and its address are removed.
# The address removal triggers an update
# of the connection's ipv6 settings,
# which causes the NMDevice to reappear.
# ip link add br0 type bridge # The new plink is associated with
# the NMDevice, managed by NM
Fixes autoconnect after the device is realized again:
# nmcli c add type team
# nmcli c up team
# nmcli d dis nm-team # autoconnect is blocked
# nmcli c del team # the is unrealized
# nmcli c add type team # the device is realized again, not
# activating with the new connection
After the device is unrealized a lot of its properites are reset. Notably, it
doesn't have an ifindex anymore so there's nothing to unconfigure really. This
makes at least NMDeviceBond unhappy:
(bond device with a slave is removed externally)
NetworkManager[21022]: <info> (bond0): device state change: activated -> unmanaged (reason 'unmanaged') [100 10 3]
NetworkManager[21022]: nm_platform_link_release: assertion 'master > 0' failed
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4ec88c3 in g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
#1 0x00007ffff4ec8a3f in g_log (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff4f3673d "%s: assertion '%s' failed")
at gmessages.c:1079
#2 0x00007ffff4ec8a79 in g_return_if_fail_warning (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", pretty_function=pretty_function@entry=0x55555575ea50 <__FUNCTION__.33801> "nm_platform_link_relea8
#3 0x000055555560559a in nm_platform_link_release (self=0x555555a27bb0 [NMLinuxPlatform], master=master@entry=0, slave=slave@entry=3) at platform/nm-platform.c:1326
#4 0x00005555555b506e in release_slave (device=<optimized out>, slave=0x555555b6d770 [NMDeviceEthernet], configure=<optimized out>) at devices/nm-device-bond.c:423
#5 0x00005555555dab7b in nm_device_master_release_one_slave (self=self@entry=0x555555bf0cc0 [NMDeviceBond], slave=0x555555b6d770 [NMDeviceEthernet], configure=configure@entry=1, reason=reason@entry=
NM_DEVICE_STATE_REASON_NOW_UNMANAGED) at devices/nm-device.c:1137
#6 0x00005555555dadb6 in nm_device_master_release_slaves (self=self@entry=0x555555bf0cc0 [NMDeviceBond]) at devices/nm-device.c:2344
#7 0x00005555555dd12f in nm_device_cleanup (self=self@entry=0x555555bf0cc0 [NMDeviceBond], reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED, cleanup_type=cleanup_type@entry=CLEANUP_TYPE_DECONFIGURE)
at devices/nm-device.c:9133
#8 0x00005555555de3ea in _set_state_full (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=
NM_DEVICE_STATE_REASON_NOW_UNMANAGED, quitting=quitting@entry=0) at devices/nm-device.c:9510
#9 0x00005555555dedb7 in nm_device_state_changed (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED)
at devices/nm-device.c:9769
#10 0x00005555555e11b4 in nm_device_unrealize (self=self@entry=0x555555bf0cc0 [NMDeviceBond], remove_resources=remove_resources@entry=0, error=error@entry=0x7fffffffd788) at devices/nm-device.c:2062
#11 0x000055555565c9c5 in _platform_link_cb_idle (data=0x555555c6e2b0) at nm-manager.c:2055
#12 0x00007ffff4ec179a in g_main_context_dispatch (context=0x555555a226c0) at gmain.c:3109
#13 0x00007ffff4ec179a in g_main_context_dispatch (context=context@entry=0x555555a226c0) at gmain.c:3708
#14 0x00007ffff4ec1ae8 in g_main_context_iterate (context=0x555555a226c0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3779
#15 0x00007ffff4ec1dba in g_main_loop_run (loop=0x555555a22780) at gmain.c:3973
#16 0x00005555555b3e5f in main (argc=1, argv=0x7fffffffdb18) at main.c:488
Do the reporting in system_create_virtual_device() only. None of the callers
checked for errors and some of the callees did issue a warning despite also
passing back a GError.
Also, drop the return value. It didn't make much sense and was not used anyway.
Fixes this:
nmcli c add type bridge # Creates and realizes the device, autoconnects connection
nmcli c del bridge # Device unrealizes
nmcli c add type bridge # The new connection does not autoconnect, since the
# device stays unrealized
Older version of iproute2 fail to add the vxlan (e.g. on Ubuntu 12.04)
Running command: ip link add nm-test-device type vxlan id 42 dev nm-test-parent local 23.1.2.164 group 239.1.2.134 ttl 0 tos 00 dstport 4789 srcport 0 0 ageing 1245
Garbage instead of arguments "id ...". Try "ip link help".
Fallback using only platform.
Strangely on Ubuntu 12.04, when not setting the port range for a vxlan
device, kernel chooses
5: nm-test-device: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN mode DEFAULT group default
link/ether 72:09:79:62:9c:45 brd ff:ff:ff:ff:ff:ff promiscuity 0
vxlan id 42 group 239.1.2.134 local 23.1.2.164 dev nm-test-parent srcport 32768 61000 dstport 4789 ageing 1245
An IPv6 address might have been added externally and the device is yet to
traverse to a connected state.
On the other hand, the externally added devices still traverse through
DISCONNECTED state and we don't want to attempt the LL addition there. Let's
check if the link still exists instead.
The macro EWOULDBLOCK is another name for EAGAIN; they are always the
same in the GNU C Library.
https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Error-Codes.html
Otherwise, we would need a workaround for EWOULDBLOCK too, because
libnl maps that to NLE_FAILURE. So we would have to detect EAGAIN
as (nle == -NLE_FAILURE && errno == EWOULDBLOCK).