Commit graph

10548 commits

Author SHA1 Message Date
Thomas Haller
5a6fc10000 connectivity: improve logging of completed connectivity check in device 2018-04-11 11:18:02 +02:00
Thomas Haller
f7127db8cf dhcp/systemd: ensure aligned memory access in ip6_start() for duid
It probably was no problem in practice, because very likely the
chunk of memory was aligned already.

Also, drop non helpful comment and fix whitespace.
2018-04-11 09:24:23 +02:00
Thomas Haller
91b1af2839 connectivity: emit properties-changed about connectivity settings 2018-04-10 15:58:12 +02:00
Thomas Haller
0a62a0e903 connectivity: schedule connectivity timers per-device and probe for short outages
It might happen, that connectivitiy is lost only for a moment and
returns soon after. Based on that assumption, when we loose connectivity
we want to have a probe interval where we check for returning
connectivity more frequently.

For that, we handle tracking of the timeouts per-device.

The intervall shall start with 1 seconds, and double the interval time until
the full interval is reached. Actually, due to the implementation, it's unlikely
that we already perform the second check 1 second later. That is because commonly
the first check returns before the one second timeout is reached and bumps the
interval to 2 seconds right away.

Also, we go through extra lengths so that manual connectivity check
delay the periodic checks. By being more smart about that, we can reduce
the number of connectivity checks, but still keeping the promise to
check at least within the requested interval.

The complexity of book keeping the timeouts is remarkable. But I think
it is worth the effort and we should try hard to

 - have a connectivity state as accurate as possible. Clearly,
   connectivity checking means that we probing, so being more intelligent
   about timeout and backoff timers can result in a better connectivity
   state. The connectivity state is important because we use it for
   the default-route penaly and the GUI indicates bad connectivity.

 - be intelligent about avoiding redundant connectivity checks. While
   we want to check often to get an accurate connectivity state, we
   also want to minimize the number of HTTP requests, in case the
   connectivity is established and suppossedly stable.

Also, perform connectivity checks in every state of the device.
Even if a device is disconnected, it still might have connectivity,
for example if the user externally adds an IP address on an unmanaged
device.

https://bugzilla.gnome.org/show_bug.cgi?id=792240
2018-04-10 15:11:23 +02:00
Thomas Haller
e8e0ef6300 connectivity: reduce timeout for connectivity checks to 20 seconds
The main issue is that `nmcli networking connectivity check` uses
nm_client_check_connectivity(), which has a timeout of 25 seconds.
Using a timeout of 30 seconds server side, means that if the requests
don't complete in time, the client side will time out and abort
with a failure. That is not right.

Fix that by using a shorter timeout server side. 20 seconds is still
plenty for a small HTTP request. If the network takes longer than that,
it's fair to call that LIMITED connectivity.
2018-04-10 15:11:23 +02:00
Thomas Haller
d8a31794c8 connectivity: rework async connectivity check requests
An asynchronous request should either be cancellable or not keep
the target object alive. Preferably both.

Otherwise, it is impossible to do a controlled shutdown when terminating
NetworkManager. Currently, when NetworkManager is about to terminate,
it just quits the mainloop and essentially leaks everything. That is a
bug. If we ever want to fix that, every asynchronous request must be
cancellable in a controlled way (or it must not prevent objects from
getting disposed, where disposing the object automatically cancels the
callback).

Rework the asynchronous request for connectivity check to

- return a handle that can be used to cancel the operation.
  Cancelling is optional. The caller may choose to ignore the handle
  because the asynchronous operation does not keep the target object
  alive. That means, it is still possible to shutdown, by everybody
  giving up their reference to the target object. In which case the
  callback will be invoked during dispose() of the target object.

- also, the callback will always be invoked exactly once, and never
  synchronously from within the asynchronous start call. But during
  cancel(), the callback is invoked synchronously from within cancel().
  Note that it's only allowed to cancel an action at most once, and
  never after the callback is invoked (also not from within the callback
  itself).

- also, NMConnectivity already supports a fake handler, in case
  connectivity check is disabled via configuration. Hence, reuse
  the same code paths also when compiling without --enable-concheck.
  That means, instead of having #if WITH_CONCHECK at various callers,
  move them into NMConnectivity. The downside is, that if you build
  without concheck, there is a small overhead compared to before. The
  upside is, we reuse the same code paths when compiling with or without
  concheck.

- also, the patch synchronizes the connecitivty states. For example,
  previously `nmcli networking connectivity check` would schedule
  requests in parallel, and return the accumulated result of the individual
  requests.
  However, the global connectivity state of the manager might have have
  been the same as the answer to the explicit connecitivity check,
  because while the answer for the manual check is waiting for all
  pending checks to complete, the global connectivity state could
  already change. That is just wrong. There are not multiple global
  connectivity states at the same time, there is just one. A manual
  connectivity check should have the meaning of ensure that the global
  state is up to date, but it still should return the global
  connectivity state -- not the answers for several connectivity checks
  issued in parallel.
  This is related to commit b799de281b
  (libnm: update property in the manager after connectivity check),
  which tries to address a similar problem client side.
  Similarly, each device has a connectivity state. While there might
  be several connectivity checks per device pending, whenever a check
  completes, it can update the per-device state (and return that device
  state as result), but the immediate answer of the individual check
  might not matter. This is especially the case, when a later request
  returns earlier and obsoletes all earlier requests. In that case,
  earlier requests return with the result of the currend devices
  connectivity state.

This patch cleans up the internal API and gives a better defined behavior
to the user (thus, the simple API which simplifies implementation for the
caller). However, the implementation of getting this API right and properly
handle cancel and destruction of the target object is more complicated and
complex. But this but is not just for the sake of a nicer API. This fixes
actual issues explained above.

Also, get rid of GAsyncResult to track information about the pending request.
Instead, allocate our own handle structure, which ends up to be nicer
because it's strongly typed and has exactly the properties that are
useful to track the request. Also, it gets rid of the awkward
_finish() API by passing the relevant arguments to the callback
directly.
2018-04-10 15:11:23 +02:00
Thomas Haller
4417b8bf3e core: add nm_utils_get_monotonic_timestamp_ns_cached() helper
Add a helper function to cache the current timestamp and return
it. The caching is a performance optimization, but it serves a
much more important purpose: repeatedly getting the timestamp
likely will yield different timings. So, commonly, within a
certain context we want to get the current time once, and stick
to that as "now".
2018-04-10 15:11:23 +02:00
Thomas Haller
43dee5f192 platform: minor cleanup of nm_platform_ip6_address_sync()
Drop the "delete_remaining" variable, and instead rely on the value of "i_know"
alone. Also, add a code comment explaining better what is happening.
2018-04-10 14:20:19 +02:00
Thomas Haller
b50d7cc653 platform: fix IPv6 address sync after for link local addresses
Since commit 78ed0a4a23 (device: add
IPv6 link local address via merge-and-apply) we handle also IPv6 link
local addresses like regular addresses. That is, we also add them during
merge-and-apply and sync them via nm_platform_ip6_address_sync().

ip6-address-sync loops over the platform addresses, to find which
addresses shall be deleted, and which shall be deleted in order to
fix the address order/priority. At that point, we must not ignore
link-local addresses anymore, but handle them too.

Otherwise, during each resync we have link local addresses, and
platform-sync thinks that the address order is wrong. That wrongly
leads to remove most addresses and re-adding them.

Fixes: 78ed0a4a23
2018-04-10 14:09:56 +02:00
Thomas Haller
ef93f6caad platform: support creating non-persistant TUN/TAP devices
For completeness, extend the API to support non-persistant
device. That requires that nm_platform_link_tun_add()
returns the file descriptor.

While NetworkManager doesn't create such devices itself,
it recognizes the IFLA_TUN_PERSIST / IFF_PERSIST flag.
Since ip-tuntap (obviously) cannot create such devices,
we cannot add a test for how non-persistent devices look
in the platform cache. Well, we could instead add them
with ioctl directly, but instead, just extend the platform
API to allow for that.

Also, use the function from test-lldp.c to (optionally) use
nm_platform_link_tun_add() to create the tap device.
2018-04-09 20:16:31 +02:00
Thomas Haller
f21ff48a84 platform/tests: extend nmtstp_wait_for_link*() to never wait
Previously, it was not (reliably) possible to use nmtstp_wait_for_link*() to
only look into the platform cache, without trying to poll the netlink
socket for events.

Add this option. Now, if the timeout is specified as zero, we never actually
read the netlink socket.

Currently, there are no callers who make use of this (by passing
a zero timeout). So, this is no change in existing behavior.
2018-04-09 20:16:31 +02:00
Thomas Haller
dd2f5cf3d4 platform/tests: implement nmtstp_assert_wait_for_link() as macro
Implement nmtstp_assert_wait_for_link() and nmtstp_assert_wait_for_link_until()
as macros, based on nmtst_assert_nonnull().

This way, the assertion will report a more helpful file:line location,
instead of being somewhere nested inside test-common.c.
2018-04-09 20:16:31 +02:00
Thomas Haller
bd8ab54b8e platform/tests: add tests for TUN/TAP handling 2018-04-09 20:16:30 +02:00
Thomas Haller
722f79c9c5 platform: workaround kernel issue for tun device for first RTM_NETLINK event
Due to a bug, the current rc-kernel will emit the first netlink
notification about tun devices before the device is initialized.

Hence, the content of the message is bogus. If the message
looks like to be this case, re-request it right away.
2018-04-09 20:16:30 +02:00
Thomas Haller
f76a94668d platform: refetch TUN link when no type-specific lnk data was received
Now that kernel supports providing information about tun/tap devices
via netlink, make use of it.

Also, enable the hack that:
  - when we first see a link that has no lnk data, we refetch
    it on the assumption, that kernel just didn't send it
    the first time.

For old kernels that do not yet support tun properties on netlink,
this means that we will always refetch the link once, the first
time we see it. I think that is acceptable, and the more correct
behavior for newer kernels that do support it.
2018-04-09 20:16:30 +02:00
Thomas Haller
031e58e1cf platform: enable parsing tun/tap properties from netlink
Now that the kernel patches are merged to mainline (rc), enable accepting
tun/tap link properties from netlink.

https://bugzilla.redhat.com/show_bug.cgi?id=1547213
2018-04-09 20:16:30 +02:00
Thomas Haller
e8a9bffdb0 platform: refactor fetching links in cache_on_change()
Rework the code to if-else-if, to not schedule the same
DELAYED_ACTION_TYPE_REFRESH_LINK instance multiple times.

Note that delayed_action_schedule() already would check that
no duplicates are scheduled, but we can avoid that.
2018-04-09 20:16:30 +02:00
Thomas Haller
28b5118ad2 platform: assert in nm_platform_link_tun_add() for unsupported options
It doesn't make sense that NetworkManager adds non-persist tun
devices, likewise, only the type IFF_TUN or IFF_TAP is supported.

Assert that the values are as expected.
2018-04-09 20:16:30 +02:00
Thomas Haller
01ad4f33ed platform: adjust format for nm_platform_lnk_tun_to_string() and print "persist"
Switch from "pi on|off" to optinally printing "pi" to indicate
whether the flag is set. That follows ip-tuntap syntax and is
more familiar:

    $ ip tuntap help
    Usage: ip tuntap { add | del | show | list | lst | help } [ dev PHYS_DEV ]
              [ mode { tun | tap } ] [ user USER ] [ group GROUP ]
              [ one_queue ] [ pi ] [ vnet_hdr ] [ multi_queue ] [ name NAME ]

    Where: USER  := { STRING | NUMBER }
           GROUP := { STRING | NUMBER }

Also, print the "persist" flag.
2018-04-09 20:16:30 +02:00
Thomas Haller
530b5755ad platform: fix double whitespace for tun device in nm_platform_lnk_tun_to_string() 2018-04-09 20:16:30 +02:00
Beniamino Galvani
4985ca5ada manager: allow autoconnect-slaves to reconnect the same connection
When a master connection is activated and has autoconnect-slaves=yes,
we want to reactivate an existing slave connection even if it is
already active.

https://bugzilla.redhat.com/show_bug.cgi?id=1548265
2018-04-08 09:40:14 +02:00
Beniamino Galvani
43a0f47ea2 core: specify an activation reason for active connections
Specify a reason when creating active connections. The reason will be
used in the next commit to tell whether slaves must be reconnected or
not if a master has autoconnect-slaves=yes.
2018-04-08 09:40:14 +02:00
Thomas Haller
ebe16abd88 core: fix freeing reg_data in error path of _obj_register()
Fixes: 640736ff65
2018-04-06 15:40:10 +02:00
Thomas Haller
d0330bfa73 auth-chain: optimize tracking of user data for NMAuthChain
- instead of allocating memory separately for the @tag (key)
  and ChainData (data), store the tag also inside ChainData.
- instead of adding two separate key and value items to GHashTable,
  use g_hash_table_add(), which is optimized for this case.
2018-04-06 11:53:00 +02:00
Thomas Haller
67828918c9 auth-chain: don't compare pointers explicitly against NULL 2018-04-05 17:45:30 +02:00
Thomas Haller
c984f0f283 auth-chain: split handling auth-call in idle
auth_call_complete() had two callers: once from the idle handler, and
once from pk_call_cb(). The conditions are slightly different, split
the function in two. For one, this allows to unset the obsolete
call_idle_id.
2018-04-05 17:45:30 +02:00
Thomas Haller
2a998075e5 auth-chain/trivial: move code 2018-04-05 17:45:30 +02:00
Thomas Haller
6335627e77 auth-chain: drop unused nm_auth_chain_get_data_ulong() 2018-04-05 17:45:30 +02:00
Thomas Haller
6f4d5b2dfb auth-chain: use CList for tracking pending authentication requests 2018-04-05 17:45:30 +02:00
Thomas Haller
011258a086 core: drop unnecessary #if WITH_POLKIT from nm-auth-subject.h
We rely on the linker to throw away unused functions.
No need for the #if in this case.
2018-04-05 17:45:30 +02:00
Thomas Haller
3f969d3b5b ifcfg-rh: suppress warning about NM_CONTROLLED=no without restricting profile to device
NM_CONTROLLED=no has the primary use of marking devices as unmanaged.
For that to work, the ifcfg file must contain either a MAC address,
an interface-name, or s390-subchannels that match a device.

In case the profile doesn't contain such specifiers, the profile
is ignored and a warning was logged:

    <warn>  [1522849679.7866] ifcfg-rh: loading "/etc/sysconfig/network-scripts/ifcfg-ens99" fails: NM_CONTROLLED was false but device was not uniquely identified; device will be managed

Downgrade this warning to a debug message. It's not unreasonable
that a user marks a ifcfg file with NM_CONTROLLED=no, to avoid
NetworkManager handling it. Yes, that way, the user did not explicitly
mark a device as unmanaged. But NetworkManager will ignore the profile,
as the user might resonably desire. No need to warn about that.
2018-04-05 11:30:14 +02:00
Thomas Haller
95d24929aa ifcfg-rh: minor cleanup setting out_ignore_error in connection_from_file_full()
- ensure that out_ignore_error is always initialized. Though,
  in practice all callers already made sure of that.
- use NM_SET_OUT() macro.
2018-04-05 11:30:14 +02:00
Thomas Haller
c4048d4d90 systemd: merge branch systemd into master 2018-04-04 17:47:22 +02:00
Thomas Haller
64708c3443 dns: fix logging path name in update_resolv_conf() 2018-04-04 16:38:18 +02:00
Thomas Haller
14098cbc07 systemd: update code from upstream (2018-04-04)
This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=c0f9017c1195b9bc3743e8dd000a18d3898b0034

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ \
             :/shared/nm-utils/siphash24.c \
             :/shared/nm-utils/siphash24.h \
             :/shared/nm-utils/unaligned.h | \
  xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_shared() {
    mkdir -p "./shared/nm-utils/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.c"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
2018-04-04 15:36:26 +02:00
Beniamino Galvani
ff678df474 core: fix infinite loop in evaluating global dns configuration
Fixes: cd48bc74b6
2018-04-04 15:31:38 +02:00
Thomas Haller
c9f89cafdf platform: adding onlink gateway route for manual addresses
Kernel does not all allow to configure a route via a gateway, if the
gateway is not directly reachable.

For non-manually added routes (e.g. from DHCP), we ignore them as a
server configuration errors. For manually added routes, we try to work
around them.

Note that if the user adds a manual route that references a gateway,
maybe he should be required to also add a matching onlink route for
the gateway (or an address that results in a device-route), otherwise
the configuration could be considered invalid. That was however not
done historically, and also, it seems a rather unhelpful behavior.
NetworkManage should just make it work, not not assume anything is
wrong with the configuration. Similarly, for IPv4, the user could
configure the route as onlink, however, that still requires extra
configuration of which the user might not be aware.

This would apply for example, when a connection has method=auto,
and would obtain the routes automatically. It seems sensible to
allow the user to add a route via the gateway, if he ~knows~ that
this particular network will provide such a configuration via DHCP.

In the past however, we tried not to automatically add a device route,
but instead see whether we will get a suitable route via DHCP. If we
wouldn't get such a route, we would however fail the connection.
However, this is really very hard to get right.
We call ip_config_merge_and_apply() possibly before receiving automatic
IP configuration (commit 7070d17ced, "device: reset
@con_ip6_config on failure before RA"). In this case, we could not yet
configure the route. Instead, we also cannot fail (yet), because we should
wait whether we will receive a route that makes this configuration
feasable.
That is hard to get right. How long should we wait? If we get a DHCP lease
and still cannot add the route, should we fail the IP configuration or wait
longer for another lease? Worse, if we decide to fail the IP configuration,
it might not fail the entire activation. Instead, we would only mark the
current address family as failed. If we later get a DHCP lease, should we
retry to add the route again? -- probably yes. If we still fail, we would
need to keep the IP configuration in failed state, regardless that DHCP
succeeded. Part of the problem is, that we are bad at tracking the
failed state per IP method. So, if manual configuration fails but DHCP
succeeds, we get the state wrong. That should be fixed separately, but it
just shows how hard it is to have this route that we currently cannot
add, and wanting to wait for something that might never come, but still
fail at some point.

Instead, if we cannot add a route due to a missing onlink gateway,
just retry and add the /32 or /128 direct route ourself.

Note that for IPv6 routes that have a "src" address which is still
TENTATIVE, we also cannot currently add the route and retry later.
However, that is fundamentally different, because:
  - the configuration here is correct, it's only that the address
    didn't yet pass IPv6 DAD and kernel is being unhelpful (rh#1457196).
  - we only have to wait a few seconds for DAD to complete or fail.
    So, it's easy to implement this sensibly.
2018-04-04 14:57:07 +02:00
Thomas Haller
78ed0a4a23 device: add IPv6 link local address via merge-and-apply
The device must not directly add addresses or routes. Instead,
it must track the addresses/routes it wants to add in the NMIP6Config.

Otherwise, during reapply, the information is lost and the next
sync will remove them.

Fixes-test: @ipv6_preserve_cached_routes
2018-04-04 14:57:07 +02:00
Thomas Haller
2a579f05fe platform: add NM_IP_CONFIG_SOURCE_IP6LL source type
We already have IP4LL and maybe should re-use that also for IPv6.
However, when adding the prefix route for IPv6 link local addresses,
we want to add it with protocol "kernel", unlike "user" for IPv4.

There is no strong reason for this. I don't think the protocol matters
much. But up to now kernel automatically adds this prefix route, so
as we are going to change that and let NetworkManager add it, keep the
protocol at "kernel".
2018-04-04 14:57:07 +02:00
Thomas Haller
d18d292b69 Revert "core: merge branch 'bg/restart-assume-rh1551958'"
This reverts commit cc1920d714, reversing
changes made to eb8257dea5.

This breaks restart, at least for Wi-Fi devices:

    #0  0x00007ffff5ee8771 in _g_log_abort (breakpoint=breakpoint@entry=1) at gmessages.c:554
    #1  0x00007ffff5ee9a5b in g_logv (log_domain=0x7ffff671a738 "GLib-GIO", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd720) at gmessages.c:1362
    #2  0x00007ffff5ee9baf in g_log (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff5f347ea "%s: assertion '%s' failed") at gmessages.c:1403
    #3  0x00007ffff5eea0f9 in g_return_if_fail_warning (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", pretty_function=pretty_function@entry=0x7ffff673fc10 <__func__.25628> "g_dbus_proxy_call_internal", expression=expression@entry=0x7ffff673fb1c "G_IS_DBUS_PROXY (proxy)") at gmessages.c:2702
    #4  0x00007ffff66cdc5f in g_dbus_proxy_call_internal (proxy=0x0, method_name=method_name@entry=0x555555810510 "Scan", parameters=0x555555c7a530, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, fd_list=fd_list@entry=0x0, cancellable=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2664
    #5  0x00007ffff66cf686 in g_dbus_proxy_call (proxy=<optimized out>, method_name=method_name@entry=0x555555810510 "Scan", parameters=<optimized out>, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, cancellable=cancellable@entry=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2970
    #6  0x000055555574e026 in nm_supplicant_interface_request_scan (self=0x555555ac2220 [NMSupplicantInterface], ssids=ssids@entry=0x0) at src/supplicant/nm-supplicant-interface.c:1821
    #7  0x00007fffe1038276 in request_wireless_scan (self=self@entry=0x555555c6ee60 [NMDeviceWifi], periodic=periodic@entry=0, force_if_scanning=force_if_scanning@entry=0, ssids=<optimized out>, ssids@entry=0x0) at src/devices/wifi/nm-device-wifi.c:1347
    #8  0x00007fffe1039011 in device_state_changed (device=0x555555c6ee60 [NMDeviceWifi], new_state=NM_DEVICE_STATE_DISCONNECTED, old_state=<optimized out>, reason=<optimized out>)
        at src/devices/wifi/nm-device-wifi.c:2998
    #9  0x00007ffff432ed1e in ffi_call_unix64 () at ../src/x86/unix64.S:76
    #10 0x00007ffff432e68f in ffi_call (cif=cif@entry=0x7fffffffdc70, fn=fn@entry=0x7fffe1038e1e <device_state_changed>, rvalue=<optimized out>, avalue=avalue@entry=0x7fffffffdb60)
        at ../src/x86/ffi64.c:525
    #15 0x00007ffff63db66f in <emit signal ??? on instance 0x555555c6ee60 [NMDeviceWifi]> (instance=instance@entry=0x555555c6ee60, signal_id=<optimized out>, detail=detail@entry=0)
        at gsignal.c:3447
        #11 0x00007ffff63bff39 in g_cclosure_marshal_generic (closure=0x555555c22ea0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gclosure.c:1490
        #12 0x00007ffff63bf73d in g_closure_invoke (closure=0x555555c22ea0, return_value=0x0, n_param_values=4, param_values=0x7fffffffdea0, invocation_hint=0x7fffffffde20) at gclosure.c:804
        #13 0x00007ffff63d1f30 in signal_emit_unlocked_R (node=node@entry=0x555555c22750, detail=detail@entry=0, instance=instance@entry=0x555555c6ee60, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffdea0) at gsignal.c:3673
        #14 0x00007ffff63dad05 in g_signal_emit_valist (instance=0x555555c6ee60, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffe0b0) at gsignal.c:3391
    #16 0x00005555556f0f18 in _set_state_full (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, quitting=quitting@entry=0) at src/devices/nm-device.c:13268
    #17 0x00005555556f1774 in nm_device_state_changed (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) at src/devices/nm-device.c:13435
    #18 0x00005555555bcf95 in recheck_assume_connection (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi]) at src/nm-manager.c:2297
    #19 0x00005555555bd53e in _device_realize_finish (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi], plink=plink@entry=0x555555ae43d8)
        at src/nm-manager.c:2473
    #20 0x00005555555c01d0 in platform_link_added (self=self@entry=0x555555b09140 [NMManager], ifindex=<optimized out>, plink=plink@entry=0x555555ae43d8, guess_assume=<optimized out>, dev_state=<optimized out>) at src/nm-manager.c:2789
    #21 0x00005555555c0cec in platform_query_devices (self=self@entry=0x555555b09140 [NMManager]) at src/nm-manager.c:2901
    #22 0x00005555555c439e in nm_manager_start (self=0x555555b09140 [NMManager], error=<optimized out>) at src/nm-manager.c:5632
    #23 0x000055555558498e in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:413
2018-04-04 14:49:04 +02:00
Thomas Haller
617bf41870 checkpoint/trivial: add fixme comments 2018-04-04 14:02:13 +02:00
Thomas Haller
8171362d02 checkpoint: minor cleanup of device_checkpoint_create()
- indent with spaces for wrapped line
- drop g_return_val_if_fail(). It really shouldn't happen,
  and if it does, we can just continue and will hit g_critical()
  warnings below, when using the variables.
- get the NMActRequest instance first, and from there the applied
  and settings connection. Not the other way around.
  nm_device_get_settings_connection() and nm_device_get_applied_connection()
  are just convenience functions to get the fields from
  act_request.
2018-04-04 14:02:13 +02:00
Thomas Haller
f67303221b checkpoint: allow resetting the rollback timeout via D-Bus
This allows to adjust the timeout of an existing checkpoint.

The main usecase of checkpoints, is to have a fail-safe when
configuring the network remotely. By allowing to reset the timeout,
the user can perform a series of actions, and keep bumping the
timeout. That way, the entire series is still guarded by the same
checkpoint, but the user can start with short timeout, and
re-adjust the timeout as he goes along.

The libnm API only implements the async form (at least for now).
Sync methods are fundamentally wrong with D-Bus, and it's probably
not needed. Also, follow glib convenction, where the async form
doesn't have the _async name suffix. Also, accept a D-Bus path
as argument, not a NMCheckpoint instance. The libnm API should
not be more restricted than the underlying D-Bus API. It would
be cumbersome to require the user to lookup the NMCheckpoint
instance first, especially since libnm doesn't provide an efficient
or convenient lookup-by-path method. On the other hand, retrieving
the path from a NMCheckpoint instance is always possible.
2018-04-04 14:02:13 +02:00
Thomas Haller
56500e5964 checkpoint: refactor setting error for lookup checkpoint failure
This changes the error reason in nm_checkpoint_manager_rollback()
from NM_MANAGER_ERROR_FAILED to NM_MANAGER_ERROR_INVALID_ARGUMENTS.
2018-04-04 14:02:13 +02:00
Thomas Haller
5c283356a1 checkpoint: allow overlapping checkpoints
Introduce a new flag NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING
that allows the creation of overlapping checkpoints. Before, and
by default, checkpoints that reference a same device conflict,
and creating such a checkpoint failed.

Now, allow this. But during rollback automatically destroy all
overlapping checkpoints that were created after the checkpoint
that is about to rollback.

With this, you can create a series of checkpoints, and rollback them
individually. With the restriction, that if you once rolled back to an
older checkpoint, you no longer can roll"forward" to a younger one.

What this implies and what is new here, is that the checkpoint might be
automatically destroyed by NetworkManager before the timeout expires. When
the user later would try to manually destroy/rollback such a checkpoint, it
would fail because the checkpoint no longer exists.
2018-04-04 14:02:13 +02:00
Thomas Haller
e5fc9a307d checkpoint: don't let nm_checkpoint_new() fail
We already do error checking in nm_checkpoint_manager_create(). No need
to split it in two places. Let all error conditions be handled by
nm_checkpoint_manager_create() first, and then once we decide all is
good, nm_checkpoint_new() can no longer fail.
2018-04-04 14:02:13 +02:00
Thomas Haller
5fb65b7f96 checkpoint: let each checkpoint schedule its own timeout
Instead of scheduling one timeout only, let each checkpoint instance
individually schedule a timeout. This has some overhead, but glib
is supposed to make scheduling many timers efficient. Otherwise,
glib should be fixed.

This simplifies in my opinion the code, because it's up to each
checkpoint to maintain its own timeout.

Later we will also add a AdjustRollbackTimeout operation, which
allow to reschedule the timeout. It also seems slightly simpler,
if scheduling of the timeout is done by the NMCheckpoint instance
itself.
2018-04-04 14:02:13 +02:00
Thomas Haller
6f28749ad4 checkpoint: simplify device_checkpoint_create() to never fail
It never failed already. Don't pretend it could.
2018-04-04 14:02:13 +02:00
Thomas Haller
e6e0eb92b9 checkpoint: minor cleanup rolling back checkpoints 2018-04-04 14:02:13 +02:00
Thomas Haller
79458a558b checkpoint: don't explicitly track checkpoints in a GHashTable
We already have a GHashTable for exported objects. We can use
that if we want to look up by path efficiently.
2018-04-04 14:02:13 +02:00