Commit Graph

18368 Commits

Author SHA1 Message Date
Thomas Haller
b524d879f0 platform: pass string buffer to nm_platform_error_to_string() and print numeric errno
Change the output of nm_platform_error_to_string() to print the numeric value.
Also, accept a string buffer instead of using an alloca() allocated buffer.

There is still a macro to provide the previous functionality, but it
was ill-suited to call from inside a loop.
2017-08-24 10:55:45 +02:00
Thomas Haller
8746dddda2 platform: assert for namespace in nm_platform_cache_update_emit_signal() 2017-08-24 10:48:04 +02:00
Thomas Haller
5a69b27a64 platform: let platform operations only consider kernel response
Also downgrade <error> logging messages to <warn>. An external
condition should never be able to trigger an <error>, and clearly
there is always a external race that can cause a netlink command
to fail.
2017-08-24 10:48:04 +02:00
Thomas Haller
774c8a811e platform: return failure reason from route-add and return only netlink response
Let nm_platform_ip_route_add() and friends return an NMPlatformError
failure reason.

Also, do_add_addrroute() did not return the response from kernel.
Instead, it determined success/failure based on the presence of the
object in the cache. That is racy and does not allow to give a failure
reason from kernel.

Instead, determine success solely based on the netlink reply from
kernel. The received errno shall be authorative, there is no need
to second guess the response.

There is a problem that netlink is not a reliable protocol. In case
of receive buffer overflow, the response is lost and we don't know
whether the command succeeded (it likely did). It's unclear how to fix
that, but for now just return "unspecified" error. We probably avoid
that already by having a huge buffer size.

Also, downgrade the error message to <warn> level. <error> is really
for bugs only.
2017-08-24 10:48:04 +02:00
Thomas Haller
fa7fafe8fd vpn: resolve route to external VPN gateway from kernel
When activating a route, we commonly need to add a route to the
external VPN gateway, so that the (encrypted) data is not sent over
the VPN itself.

Currently, our VPN connections are rather strongly tied to their
parent device. Maybe the shouldn't be, as VPN may happily support
changing the route from one device/IP address to another.

Anyway, our previous way to determine the gateway for the route
was not great. Instead, ask kernel how to reach the gateway via
(something like) `ip route get`. If kernel would route the packets
to the gateway via our parent device, we take that gateway.

If not, we keep our previous heuristic (which is probably wrong
in this case).
2017-08-24 10:48:03 +02:00
Thomas Haller
33a2a7c3e3 platform: add nm_platform_ip_route_get() for route-lookup
Inspired from iproute2. As such, don't use libnl3's "struct nl_msg", but
add _nl_addattr_l() and use a stack-allocated "struct nlmsghdr". With
this, we are closer to the raw netlink API. It really is simple enough.

The complicated part of the patch is that we re-use the existing netlink
socket for events. Hence, we must process the socket via our common
event_handler_recvmsgs(). That also means, that we get the netlink
response a few layers down the stack and have to return the result
via DelayedActionWaitForNlResponseData.
2017-08-24 10:48:03 +02:00
Thomas Haller
fec80e7473 platform: use IFA_F_NOPREFIXROUTE flag for IPv4 addresses
For IPv6 addresses we use IFA_F_NOPREFIXROUTE for a long time.
If we detect that kernel does not support the flag (for IPv6), we
add addresses as /128 to prevent kernel from adding an onlink route.
We add IPv6 device routes explicitly, whenever needed according
to the onlink RA flag.

For IPv4, we also don't want the route added by kernel. The reason is
that is has an undesired metric of zero. However, usually we want the route
to have a different metric. The complicated part is that kernel does
not add the route immediately but sometimes later. For that we have
nm_platform_ip4_dev_route_blacklist_set() (previously that was
nm_route_manager_ip4_route_register_device_route_purge_list()). It
watches the interface and when a registered device route shows up,
it deletes it.

The better solution is to use the IFA_F_NOPREFIXROUTE flag to prevent
the creation of the route in the first place. It was added for IPv4 to
kernel in commit 7b1311807f3d3eb8bef3ccc53127838b3bea3771, October 2015.

Contrary to IPv6, we cannot (easily) detect whether kernel supports IFA_F_NOPREFIXROUTE
for IPv4 routes. Hence keep nm_platform_ip4_dev_route_blacklist_set() for older
kernels.
2017-08-24 10:48:03 +02:00
Thomas Haller
2f83894498 core: cleanup setting ifa_flags in ndisc_config_changed()
Some refactoring and one change:

If we don't have system-support, don't set IFA_F_MANAGETEMPADDR.
2017-08-24 10:48:03 +02:00
Thomas Haller
057b63979e core: move setting NDisc addresses/routes to NMIP6Config
Add an utility function for resetting addresses/routes of NMIP6Config
from NMNDisc data. For one, this de-duplicates code in device and
nm-iface-helper.

Also, we no longer first reset (delete) all addresses and add them anew.
Instead, we first mark all entries as dirty for deletion, merge (append)
the new entires, and delete the remaining dirty entires. This saves a
extra work, in the expected case where NMIP6Config already contains
several of the new entries.
2017-08-24 10:48:03 +02:00
Lubomir Rintel
1b3a0208d9 all,trivial: include kernel versions and release dates in comments
This will make us stop worry how relevant are chunks of compat code with
older kernels when deciding whether it's worth supporting/testing them.
As if we actually were testing old kernels.
2017-08-24 10:48:03 +02:00
Thomas Haller
8670aacc7c platform: cleanup detecting kernel support for IFA_FLAGS and IPv6LL
- cache the result in NMPlatformPrivate. No need to call the virtual
  function every time. The result is not ever going to change.

- if we are unable to detect support, assume support. Those features
  were added quite a while ago to kernel, we should default to "support".
  Note, that we detect support based on the presence of the absence of
  certain netlink flags. That means, we will still detect no support.
  The only moment when we actually use the fallback value, is when we
  didn't encounter an RTM_NEWADDR or AF_INET6-IFLA_AF_SPEC message yet,
  which would be very unusual, because we fill the cache initially and
  usually will have some addresses there.

- for no strong reason, track "undetected" as numerical value zero,
  and "support"/"no-support" as 1/-1. We already did that previously for
  _support_user_ipv6ll, so this just unifies the implementations.
  The minor reason is that this puts @_support_user_ipv6ll to the BSS
  section and allows us to omit initializing priv->check_support_user_ipv6ll_cached
  in platforms constructor.

- detect _support_kernel_extended_ifa_flags also based on IPv4
  RTM_NEWADDR messages. Originally, extended flags were added for IPv6,
  and later to IPv4 as well. Once we see an IPv4 message with IFA_FLAGS,
  we know we have support.
2017-08-24 10:48:03 +02:00
Thomas Haller
48bc116c20 platform/trivial: move code 2017-08-24 10:48:03 +02:00
Thomas Haller
f0de7d347f platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because

 - when configuring routes, multiple (managed) interfaces may get
   conflicting routes (multihoming). Only one of the routes can be actually
   configured using `ip route replace`, so we need to track routes that are
   currently shadowed.

 - when configuring routes, we might replace externally configured
   routes on unmanaged interfaces. We should not interfere with such
   routes.

That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.

Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.

It practice it is a bit more complicated because:

 - when adding an IPv4 address, kernel will automatically create a device route
   for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
   IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
   addresses yet (and we don't require such a kernel yet), we still need functionality
   similar to nm_route_manager_ip4_route_register_device_route_purge_list().
   This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().

 - trying to configure an IPv6 route with a source address will be rejected
   by kernel as long as the address is tentative (see related bug rh#1457196).
   Preferably, NMDevice would keep the list of routes which should be configured,
   while kernel would have the list of what actually is configured. There is a
   feed-back loop where both affect each other (for example, when externally deleting
   a route, NMDevice must forget about it too). Previously, NMRouteManager would have
   the task of remembering all routes which we currently want to configure, but cannot
   due to conflicting routes.
   We get rid of that, because now we configure non-exclusive routes. We however still
   will need to remember IPv6 routes with a source address, that currently cannot be
   configured yet. Hence, we will need to keep track of routes that
   currently cannot be configured, but later may be.
   That is still not done yet, as NMRouteManager didn't handle this
   correctly either.
2017-08-24 10:48:03 +02:00
Thomas Haller
974ff62996 platform: fix handling rt_scope of IPv4 route
Kernel does not allow to add an IPv4 route with rt_scope RT_SCOPE_NOWHERE
(255). It would fail with EINVAL.

While adding a route, we coerce/normalize the scope in
nm_platform_ip_route_normalize(). However, that should only be
done, if the scope is not explicitly set already. Otherwise,
leave it unchanged.

nm_platform_ip_route_normalize() is related to the compare functions.
Several compare modes do a fuzzy comparison, and they should compare
equal as if they would be normalized. Hence, we must do the same
normalization there.

One pecularity in NetworkManager is that we track scope as it's
inverse. The reason is to have a default value of zero meaning
RT_SCOPE_NOWHERE. Hence "scope_inv".
2017-08-24 10:47:23 +02:00
Thomas Haller
69a50a5053 platform: add and use nm_platform_ip_route_normalize()
Adding a route to kernel may coerce/mangle some properties. Add a function
nm_platform_ip_route_normalize() to simulate these changes.
2017-08-23 18:37:22 +02:00
Thomas Haller
990a050aff platform: cleanup and renaming of nm_platform_address_flush() function
Rename to nm_platform_ip_address_flush(), it's more consistent with naming
for other platform functions.

Also, pass an address family argument. Sometimes I feel an option makes it clearer
what the function does. Otherwise, from the name it's not clear which address
families are affected. As an API, it feels more correct to me.

We soon also get a nm_platform_ip_route_flush() function, which will
look similar.
2017-08-23 18:37:22 +02:00
Thomas Haller
a738a3446b platform: add typedef for NMPObjectPredicateFunc function pointer
Otherwise, casting a function pointer is cumbersome.
2017-08-23 18:37:22 +02:00
Thomas Haller
936ebdc724 core: consistently use _nm_ip_config_add_obj() when adding route/address to ip-config
_nm_ip_config_add_obj() does some additional checking, like setting the ifindex.
We shall not bypass this also during bulk-update (replace).

Add options @merge and @append_force to make _nm_ip_config_add_obj() suitable
in those cases too, and use it.
2017-08-23 18:37:22 +02:00
Thomas Haller
29bfe7c1fd core: merge code block in nm_ip4_config_commit() by un-indenting 2017-08-23 18:37:22 +02:00
Thomas Haller
35ed678cc6 platform: add nm_platform_ip_route_add() function 2017-08-23 18:37:22 +02:00
Thomas Haller
abaaf3a693 platform/trivial: move code
Trivial code (like this which only depends on an enum defined in a header
file) should go first, so that the complex stuff is close together.
2017-08-23 18:37:22 +02:00
Thomas Haller
2cd25d7a37 platform: fix constness of argument for nm_platform_lookup_all()
... and nm_platform_lookup_entry().
2017-08-23 18:37:22 +02:00
Thomas Haller
b0f52d41bc platform: fix handling rt_source/rtprot when comparing routes
In several cases, does the route compare function a fuzzy match, to get
the result as what would happen if you add that route to kernel.

The rt_source enum contains some NetworkManager specific values which
are mapped to a certain rtm_protocol value. Especially, when adding
a route to kernel, the resulting value will be coerced (and end up being
different).

We must take this coercion into account.
2017-08-23 18:37:22 +02:00
Thomas Haller
d85c239101 platform: fix loose comparison for metric of IPv6 routes
For IPv6 routes, a metric of zero is identical to a metric of 1024.
Unless we do NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, compare them as
equal.
2017-08-23 18:37:22 +02:00
Thomas Haller
ffd47da5dc platform: use _Generic() for NM_PLATFORM_IP_ROUTE_IS_DEFAULT() macro
Avoid the plain cast and use _Generic() to check the type of @route argument.
2017-08-23 18:37:21 +02:00
Thomas Haller
2f693fb68c shared: return deleted object from nm_dedup_multi_index_remove_obj()
For completeness of the API. remove_obj() is basically a shortcut
of nm_dedup_multi_index_lookup_obj() combined with
nm_dedup_multi_index_remove_entry(). As such, it is useful to return
the actually deleted object. Note that the lookup needle @obj is not
necessarily the same instance as the one that will be removed, it's
only an instance that compares equal according to the index's equality
operator.
2017-08-23 18:37:21 +02:00
Thomas Haller
3fc501e833 shared: indicate changes when only reordering happens during nm_dedup_multi_index_add()
The return value shall indicate whether the add-call changed anything.
Reordering shall count as a change too.

On the other hand, clearing the dirty flag of the entry does not count
as a change.
2017-08-23 18:37:21 +02:00
Thomas Haller
d100ce28e0 shared: add nm_g_slice_free_fcn() util
Useful, when you need a GDestroyNotify function for g_slice_free() of
a certain type.
2017-08-23 18:37:21 +02:00
Thomas Haller
3faff5b457 core/trivial: indentation in src/devices/nm-device-ip-tunnel.c 2017-08-23 18:37:21 +02:00
Thomas Haller
20235453a9 core: fix crash in nm_ip4_config_address_exists()
Fixes: 22edeb5b69
2017-08-23 18:37:21 +02:00
Lubomir Rintel
9481bda939 clients: don't default Bluetooth to the PANU profile
No reason to, the other types are no less likely. Quite the contrary, if
the user specifies a GSM APN we're sure to use a DUN profile.

  $ ./clients/cli/nmcli c add type bluetooth ifname '*' bluetooth.bdaddr 1C:E2:CC:56:6C:45 apn internet
  $ nmcli c show bluetooth-1 |grep bluetooth.type
  bluetooth.type:                         panu
                                          ^^^^ not cool
2017-08-23 16:19:32 +02:00
Lubomir Rintel
9b28c9ba91 core: infer the bluetooth type from the presence of the supplemental settings
When the user sets a GSM or CDMA setting along with a Bluetooth setting
we know we're dealing with a DUN profile. No need to ask.

[thaller@redhat.com: verify() and normalize() must strongly agree whether a
connection is normalizable, and now to do it. That is, after verify()
determines the connection is normalizable, normalize() must fix it as
anticipated.

The reason is, we only want to modify the connection, if we are able
to create a valid result. Hence, after normalize() it *must* verify().

Try to simplify that by moving the logic of fixing the bt-type to a
common place _nm_connection_detect_bluetooth_type().]

Co-Authored-By: Thomas Haller <thaller@redhat.com>
2017-08-23 16:18:44 +02:00
Lubomir Rintel
0718b25508 clients: allow GSM and CDMA for Bluetooth connections
Unbreaks Bluetooth DUN. Probably broken with the nm-meta-setting-desc
refactor, hence the Fixes tag. I didn't actually check.

  $ nmcli c add type bluetooth ifname '*' bluetooth.bdaddr 1C:E2:CC:56:6C:45 connection.id bt bt-type dun-gsm
  Error: 'apn' argument is required.
  $ nmcli c add type bluetooth ifname '*' bluetooth.bdaddr 1C:E2:CC:56:6C:45 connection.id bt bt-type dun-gsm apn internet
  Error: invalid <setting>.<property> 'apn'.
  $

This is where it starts to get sad ^

  $ nmcli c add type bluetooth ifname '*' bluetooth.bdaddr 1C:E2:CC:56:6C:45 connection.id bt bt-type dun-gsm gsm.apn internet
  Error: invalid or not allowed setting 'gsm': 'gsm' not among [connection, bluetooth, bridge, ipv4, ipv6, proxy].
  $

This is where it gets obvious what went wrong ^

Fixes: b5c8622ad3
2017-08-23 16:08:42 +02:00
Francesco Giudici
5df2c96be0 device: skip creating VLAN devices if parent device is not ready yet
do a check on parent ifindex before calling "nm_device_supports_vlans"
otherwise if the parent device is a software device and its ifindex
member has not been updated yet we will trigger the g_return_if_fail
statement in "nmp_cache_lookup_entry_link".

This has been osserved in NetworkManager CI test suite, on NetworkManager
boot, during the creation of a vlan on top of a bond interface.

CI test: vlan_update_mac_from_bond

    [...]
    <info>  [1503323670.0229] manager: (bond0): new Bond device (/org/freedesktop/NetworkManager/Devices/23)
    <debug> [1503323670.0231] device[0x555555c3e320] (vlan10): constructed (NMDeviceVlan)
    <debug> [1503323670.0231] manager: (vlan-vlan10) create virtual device vlan10
    <debug> [1503323670.0231] device[0x555555c3e320] (vlan10): unmanaged: flags set to [platform-init,!sleeping=0x10/0x11/unmanaged/unrealized], set-managed [sleeping=0x1])
    <trace> [1503323670.0235] exported-object[0x555555c3e320]: export: "/org/freedesktop/NetworkManager/Devices/24"
    <trace> [1503323670.0235] properties-changed[0x555555c3e320]: ignoring notification for prop g-object-path on type NMDeviceVlan
    <trace> [1503323670.0236] properties-changed[0x555555c3e320]: ignoring notification for prop path on type NMDeviceVlan
    <info>  [1503323670.0237] manager: (vlan10): new VLAN device (/org/freedesktop/NetworkManager/Devices/24)
    <debug> [1503323670.0239] device[0x555555c3e320] (vlan10): create (is nm-owned)

    Program received signal SIGTRAP, Trace/breakpoint trap.
    g_logv (log_domain=0x5555557c39a9 "NetworkManager", log_level=
        G_LOG_LEVEL_CRITICAL, format=<optimized out>,
        args=args@entry=0x7fffffffdef0) at gmessages.c:1086
    1086		  g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));

    (gdb) bt

    #0  0x00007ffff5ce3643 in g_logv (log_domain=0x5555557c39a9 "NetworkManager", log_level=
        G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffdef0) at gmessages.c:1086
    #1  0x00007ffff5ce37bf in g_log (log_domain=log_domain@entry=0x5555557c39a9 "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff5d51190 "%s: assertion '%s' failed") at gmessages.c:1119
    #2  0x00007ffff5ce37f9 in g_return_if_fail_warning (log_domain=log_domain@entry=0x5555557c39a9 "NetworkManager", pretty_function=pretty_function@entry=0x5555557b2a20 <__func__.32407> "nmp_cache_lookup_entry_link", expression=expression@entry=0x5555557b1037 "ifindex > 0") at gmessages.c:1128
    #3  0x000055555566688a in nmp_cache_lookup_entry_link (cache=0x555555a780f0, ifindex=<optimized out>) at src/platform/nmp-object.c:1449
    #4  0x00005555556668f9 in nmp_cache_lookup_link (cache=<optimized out>, ifindex=ifindex@entry=0) at src/platform/nmp-object.c:1464
    #5  0x00005555556515e9 in nm_platform_link_get_obj (self=self@entry=0x555555a88880 [NMLinuxPlatform], ifindex=ifindex@entry=0, visible_only=visible_only@entry=1) at src/platform/nm-platform.c:618
    #6  0x0000555555633e91 in link_supports_vlans (platform=0x555555a88880 [NMLinuxPlatform], ifindex=0) at src/platform/nm-linux-platform.c:4482
    #7  0x00005555556d6d41 in create_and_realize (device=0x555555c3e320 [NMDeviceVlan], connection=0x7fffdc007890, parent=0x555555c33560 [NMDeviceBond], out_plink=0x7fffffffe1f8, error=0x7fffffffe358) at src/devices/nm-device-vlan.c:239
    #8  0x00005555556b934c in nm_device_create_and_realize (self=self@entry=0x555555c3e320 [NMDeviceVlan], connection=connection@entry=0x7fffdc007890, parent=0x555555c33560 [NMDeviceBond], error=error@entry=0x7fffffffe358)
        at src/devices/nm-device.c:2946
    #9  0x00005555555b84c7 in connection_changed (connection=0x7fffdc007890, self=0x555555ab1070 [NMManager]) at src/nm-manager.c:1381
    #10 0x00005555555b84c7 in connection_changed (self=0x555555ab1070 [NMManager], connection=0x7fffdc007890) at src/nm-manager.c:1431
    #11 0x00005555555b9130 in retry_connections_for_parent_device (self=self@entry=0x555555ab1070 [NMManager], device=device@entry=0x555555c33560 [NMDeviceBond])
        at src/nm-manager.c:1416
    #12 0x00005555555b95c7 in add_device (self=self@entry=0x555555ab1070 [NMManager], device=device@entry=0x555555c33560 [NMDeviceBond], error=error@entry=0x7fffffffe598) at src/nm-manager.c:2238
    #13 0x00005555555b83e1 in connection_changed (connection=0x7fffdc007b30, self=0x555555ab1070 [NMManager]) at src/nm-manager.c:1352
    #14 0x00005555555b83e1 in connection_changed (self=0x555555ab1070 [NMManager], connection=0x7fffdc007b30) at src/nm-manager.c:1431
    #15 0x00005555555be25b in nm_manager_start (self=0x555555ab1070 [NMManager], error=error@entry=0x7fffffffe720) at src/nm-manager.c:5202
    #16 0x0000555555586b13 in main (argc=1, argv=0x7fffffffe888) at src/main.c:413
2017-08-22 11:54:37 +02:00
Thomas Haller
a3e84daf44 libnm/build: un-export wrong symbols for nm-manager.h
libnm/nm-manager.h is a private header file. It's symbols
should not be exported.

Fixes: 75aa3ea194
2017-08-21 12:19:27 +02:00
Thomas Haller
13f955db58 config: write connectivity=true to internal state file
The internal state file is supposed to overwrite the files from /etc.
Hence, we must also explicitly enable connectivity checking, when the
user wishes to do so. Otherwise, if /etc contains connectivity=false,
the setting cannot be overruled via D-Bus.
2017-08-21 12:18:13 +02:00
Thomas Haller
804b2c2365 config/tests: remove test artifact after test_config_connectivity_check()
Fixes: 9a58ee0705
2017-08-18 21:42:22 +02:00
Thomas Haller
17f0c19473 platform: fix updating object in nmp_cache_update_netlink_route()
_idxcache_update() may remove @entry_old or it may update @entry_old
in-place.

We must assign @out_obj_old before and not touch @entry_old after
_idxcache_update().

Fixes: cdd8c65799
2017-08-18 11:32:29 +02:00
Thomas Haller
75aa3ea194 libnm/connectivity: fix exporting new connectivity ABI in linker version script
Fixes: 0480dae749
2017-08-17 23:27:31 +02:00
Thomas Haller
2eb02543c2 connectivity: merge branch 'connectivity-enable-dbus-bgo785117'
https://bugzilla.gnome.org/show_bug.cgi?id=785117
https://github.com/NetworkManager/NetworkManager/pull/23
https://mail.gnome.org/archives/networkmanager-list/2017-July/msg00035.html
2017-08-17 23:15:43 +02:00
Thomas Haller
24a732c8e7 cli: show new enable-disable-connectivity-check permission 2017-08-17 23:09:07 +02:00
Thomas Haller
72baa8e30b libnm: add gtk-doc Since markers for new API and missing enum documentation 2017-08-17 23:08:44 +02:00
James Henstridge
0480dae749 client: expose connectivity-check-{available,enabled} properties
https://bugzilla.gnome.org/show_bug.cgi?id=785117
2017-08-17 22:31:47 +02:00
James Henstridge
4dd30b784c manager: add connectivity-check-{available,enabled} properties.
https://bugzilla.gnome.org/show_bug.cgi?id=785117
2017-08-17 22:31:47 +02:00
James Henstridge
9a58ee0705 config: add an API to disable connectivity check via internal config file.
https://bugzilla.gnome.org/show_bug.cgi?id=785117
2017-08-17 22:31:47 +02:00
Thomas Haller
c0ac4a2fdd platform: merge branch 'th/platform-route-pt2'
Fix the platform cache for routes, to be able to track routes
like they can be added to kernel. Basically, the previous notion
of the identifier for routes (ifindex,network/plen,metric) was
not what kernel does.

NMRouteManager and other code outside of platform is still oblivious
to this change. That has to be addressed in future commits.

https://github.com/NetworkManager/NetworkManager/pull/24
2017-08-12 16:19:50 +02:00
Thomas Haller
94560e4ad2 platform: cleanup nmp_lookup_init_route_visible() lookup helper
nmp_lookup_init_route_visible() was originally named this way, to only return routes
that are nmp_object_is_visible(). However, all routes are visible (as long as they are
nmp_object_is_alive()). Hence, this is a historic misnomer.

Also, passing @only_default FALSE is identical to the
nmp_lookup_init_addrroute() lookup.

So, rename the function to indicate it is a lookup for default routes
only. Also, get rid of the unsupported ifindex argument for which there
is no index.
2017-08-12 16:04:28 +02:00
Thomas Haller
3ec110b67e platform: drop workaround for deleting IPv4 routes with metric zero
Deleting an IPv4 route with metric zero will either delete the intended route,
or if no such route exists, it will delete another existing route with different
metric (but otherwise matching parameters).

I think this is a shortcoming of the kernel API. It allows omitting
the metric during delete. However, it gives not way to express to
explicitly delete an IPv4 route with metric zero, but no other.

Since we only delete routes that we obtain from the platform cache
in the first place, we don't need the workaround. Of course, there
is still a race that platform cache might be out of date at the
moment we attempt to delete the route. Or the cache might be
inconsistent, both cases leading to deletion of the wrong route.
But such cases should be very rare, and only present when the user
changes the routing table outside of NM.
2017-08-12 16:04:28 +02:00
Thomas Haller
cdd8c65799 platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.

Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.

Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.

Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:

    # ip -d -4 route show dev v
    # ip monitor route &
    # ip route add 192.168.5.0/24 dev v
    192.168.5.0/24 dev v scope link
    # ip route change 192.168.5.0/24 dev v scope 10
    192.168.5.0/24 dev v scope 10
    # ip -d -4 route show dev v
    unicast 192.168.5.0/24 proto boot scope 10

Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.

Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-12 16:04:28 +02:00
Thomas Haller
94c025452b platform: preserve order of objects during dump
NMPCache can preserve the order of the objects. Until now, the order
was however arbitrary. Soon we will require to preserve the order of
routes.

During a dump, force appending new objects at the end. That ensures,
correct ordering during the dump.

Note that we track objects in several distrinct indexes. Those partition the
set of all objects. Outside a dump when receiving events about new objects (e.g.
RTM_NEWROUTE), it is very unclear at which place the new object should be sorted.
It is especially unclear, as an object might move from one partition (of
an index) to another.
In general, a deterministic order will only be useful in one particular
instance: the NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION index for routes.
In this case, we will ensure a particular order of the routes.
2017-08-12 16:02:11 +02:00