Commit graph

463 commits

Author SHA1 Message Date
Thomas Haller
7459548f23 core: return remaining lifetime from nm_utils_lifetime_get()
nm_utils_lifetime_get() already has so many arguments.
Essentially, the function returned %TRUE if and only if the
lifetime was greater then zero.

Combine the return value and the output argument for the lifetime.

It also matches better the function name: to get the lifetime.
2018-02-09 17:40:01 +01:00
Thomas Haller
06b968a820 platform: add nm_platform_refresh_all() API
Add a function that allows to re-request all objects of a certain type.
Usually, the cache is supposed to keep itself in a consistent state and
this function is not useful.

It is however useful during testing and debugging to explicitly reload
an object type.

If you ever think to need this function in non-testing code, then
something else is probably wrong with the cache implementation.
2018-02-09 17:40:01 +01:00
Thomas Haller
54b2e8d679 platform: allow omitting output arguments for nm_utils_lifetime_get()
At various places we don't need the output argument. Allow to omit it,
which cleans up the caller.
2018-02-07 13:42:24 +01:00
Thomas Haller
d2871e453f platform: reorder printing address flags in nm_platform_addr_flags2str()
Print the "tentative" flags as last. Most other flags, have more the character of
a user configured attribute, while "tentative" reflects the current state of the address.

Previously, we would log
    secondary,tentative
and
    tentative,mngtmpaddr,noprefixroute

Print the "tenative" flag last. This way, the flag that commonly
will flip by kernel's decision, is consistently printed last.
2018-02-07 13:41:52 +01:00
Thomas Haller
8b4f119272 core: avoid IFA_F_TEMPORARY alias for IFA_F_SECONDARY
IFA_F_SECONDARY and IFA_F_TEMPORARY have the same numerical values,
and are synonymous. Consistently use IFA_F_SECONDARY.
2018-02-07 13:37:12 +01:00
Lubomir Rintel
8a46b25cfa all: require glib 2.40
RHEL 7.1 and Ubuntu 14.04 LTS both have this.

https://bugzilla.gnome.org/show_bug.cgi?id=792323
2018-01-18 11:45:36 +01:00
Beniamino Galvani
da4c9e51a0 ip-tunnel: add support for tunnel flags
Implement support for IP tunnel flags. Currently only some IPv6 tunnel
flags are supported. Example:

 # nmcli connection add type ip-tunnel mode ip6ip6 \
   ip-tunnel.flags ip6-ign-encap-limit,ip6-use-orig-tclass \
   ifname abc ip-tunnel.parent ens8 ipv4.method disabled \
   ipv6.method manual ipv6.address ::8888 remote ::42

 # ip -d l
  61: abc@ens8: <NOARP,UP,LOWER_UP> mtu 1460 qdisc noqueue ...
    link/tunnel6 :: brd ::42 promiscuity 0
    ip6tnl ip6ip6 remote ::42 local :: dev ens8 encaplimit none
    hoplimit 0 tclass inherit ...

https://bugzilla.gnome.org/show_bug.cgi?id=791846
2018-01-05 18:25:08 +01:00
Beniamino Galvani
ffc04e178b platform: fix ipv6 address synchronization
The @keep_link_local logic was wrong: when set to TRUE we must not
delete addresses and when set to FALSE we must delete addresses only
if they are unknown.

Also, ignore link-local addresses when comparing positions.

Fixes: 19d6d54b6f
2017-12-15 09:56:00 +01:00
Beniamino Galvani
19d6d54b6f platform: improve ipv6 addresses synchronization
nm_platform_ip6_address_sync() must take care not only of adding
missing addresses and removing unknown addresses, but also of the
order in which they are added. The order is important because it
determines which address is preferred by kernel.

Since we can only add addresses at the top of the list, in order to
change the position of an address we must first remove it and then
re-add it in the right position.
2017-12-12 15:17:10 +01:00
Thomas Haller
62d4dba74b platform: assert() for valid item in nm_platform_link_get_all()
Coverity thinks that item might be NULL, but actually it
cannot. Unclear how to avoid the false positive.
2017-12-12 11:15:38 +01:00
Thomas Haller
27e8fffdb8 platform: fix crash hashing NMPlatformTfilter and NMPlatformQdisc
@kind might be NULL. There are 3 forms of the hash-update functions for
string: str(), str0(), and strarr().

- str0() is when the string might be NULL.
- str() does not allow the string to be NULL
- strarr() is like str(), except it adds a G_STATIC_ASSERT()
  that the argument is a C array.

The reason why a difference between str() and str0() exists, is
because str0() hashes NULL different from a "" or any other string.
This has an overhead, because it effectively must hash another bit
of information that tells whether a string was passed or not.

The reason is, that hashing a tupple of two strings should always
yield a different hash value, even for "aa",""; "a","a"; "","aa",
where naive concatentation would yield identical hash values in all
three cases.

Fixes: e75fc8279b
2017-12-12 11:15:38 +01:00
Thomas Haller
fe3d7209e7 platform: fix TC to-string/hash/cmp functions to include the action
Also add a define NM_PLATFORM_ACTION_KIND_SIMPLE. It makes the
uses of "simple" grepable.
2017-12-11 11:08:41 +01:00
Lubomir Rintel
b0fd3ecbaf platform: add support for traffic filters 2017-12-11 11:08:41 +01:00
Lubomir Rintel
ff9f27eb12 platform: add support for queueing disciplines 2017-12-11 10:52:22 +01:00
Thomas Haller
7573594a21 platform: merge nm_platform_*_delete() delete functions
It only makes sense to call delete() with NMPObjects that
we obtained from the platform cache. Otherwise, if we didn't
get it from the cache in the first place, we wouldn't know
what to delete.

Hence, the input argument is (almost) always an NMPObject
in the first place. That is different from add(), where
we might create a new specific NMPlatform* instance on the
stack. For add() it makes slightly more sense to have different
functions depending on the type. For delete(), it doesn't.
2017-12-11 10:30:26 +01:00
Lubomir Rintel
93ac0e455b platform/trivial: s/ADDRROUTE/OBJECT/ for the cache lookup
It's going to be useful for other objects that have a type (of course)
and an ifindex.
2017-12-11 10:30:26 +01:00
Thomas Haller
653aab70ac platform: preserve errno in nm_platform_sysctl_get_int_checked()
It's not clear whether free() changes errno. Be sure about it.

https://bugzilla.gnome.org/show_bug.cgi?id=790726
2017-11-24 17:06:42 +01:00
Thomas Haller
93adadbdcb all: use nm_direct_hash() instead of g_direct_hash()
We also do this for libnm, where it causes visible changes
in behavior. But if somebody would rely on the hashing implementation
for hash tables, it would be seriously flawed.
2017-11-16 11:49:52 +01:00
Thomas Haller
b58481b31e all: don't use g_direct_equal() for hash table equality function
GHashTable optimizes a NULL equality function to use direct pointer
comparison. That saves the overhead of calling g_direct_equal().
This is also documented behavior for g_hash_table_new().

While at it, also don't pass g_direct_hash() but use the default
of %NULL. The behavior is the same, but consistently don't use
g_direct_hash().
2017-11-16 11:49:51 +01:00
Thomas Haller
88a40f960c platform: consider RTNH_F_ONLINK onlink flag for IPv4 routes
The "onlink" flag for IPv4 routes is part of the route ID.
Consider it in nm_platform_ip4_route_cmp().

Also, allow configuring the flag when adding a route.

Note that for IPv6, the onlink flag is still ignored.
Pretty much like kernel does.
2017-11-13 11:35:44 +01:00
Thomas Haller
81778f59f2 platform: track all rtm_flags for routes 2017-11-13 11:35:44 +01:00
Thomas Haller
54cbb321e5 platform: return platform error code from nm_platform_link_set_mtu() 2017-10-24 16:05:40 +02:00
Thomas Haller
32b3eb1181 core: merge IPv4 and IPv6 implementation of nm_utils_ip4_property_path()
and nm_utils_ip6_property_path().

Also, rename to nm_utils_sysctl_ip_conf_path().
2017-10-24 16:05:40 +02:00
Thomas Haller
6e01238a40 core: don't use static buffer for nm_utils_ip4_property_path()
and nm_utils_ip6_property_path(). The API with static buffers
looks a bit nicer. But I think they are dangerous, because
we tend to pass the buffer down several layers of the stack, and
it's not immediately clear, that we don't overwrite the static
buffer again (which we probably did not, but it's hard to verify
that there is no bug there).
2017-10-24 16:04:46 +02:00
Thomas Haller
42cfcf6f23 platform: downgrade warning about failure to set MTU
Setting the MTU failes under regular conditions, for example when
setting the MTU of a master larger then the MTU of the slaves.

Logging a warning it too alarming.
2017-10-23 17:53:22 +02:00
Thomas Haller
1410c6376e platform: don't hash the compare type in nm_platform_ip4_route_hash_update()
We don't need this extra distinguisher. It makes no sense to ever
compare two routes with a different compare-type.

Also, the number of fields that is hashed already differs between each
compare type. If we have a good hashing algorithm, this already suffices
that the hash value looks largely different.
2017-10-18 13:29:22 +02:00
Thomas Haller
f17a20c568 core: refactor hashing to use reduce calls to siphash24_compress()
This makes for example nm_platform_link_hash_update() by roughly 25%
faster.
2017-10-18 13:29:22 +02:00
Thomas Haller
cfe8546df9 all: extend hash functions with an NMHashState argument
We often want to cascade hashing, meaning, to combine the
outcome of various hash functions in a larger hash.

Instead of having each hash function return a guint hash value,
accept a hash state argument. This saves the overhead of initializing
and completing the intermediate hash states.
It also avoids loosing entropy when we reduce the larger hash state
into the intermediate guint hash value.
2017-10-18 13:29:22 +02:00
Thomas Haller
2f56de7492 all: add helper functions for nm_hash_update*()
By using a macro, we don't cast all the types to guint. Instead,
we use their native types directly. Hence, we don't need
nm_hash_update_uint64() nor nm_hash_update_ptr().
Also, for types smaller then guint like char, we save hashing
the all zero bytes.
2017-10-18 13:29:22 +02:00
Thomas Haller
ee76b0979f all: use siphash24 for hashing
siphash24() is wildly used by projects nowadays.

It's certainly slower then our djb hashing that we used before.
But quite likely it's fast enough for us, given how wildly it is
used. I think it would be hard to profile NetworkManager to show
that the performance of hash tables is the issue, be it with
djb or siphash24.

Certainly with siphash24() it's much harder to exploit the hashing
algorithm to cause worst case hash operations (provided that the
seed is kept private). Does this better resistance against a denial
of service matter for us? Probably not, but let's better be safe then
sorry.

Note that systemd's implementation uses a different seed for each hash
table (at least, after the hash table grows to a certain size).
We don't do that and use only one global seed.
2017-10-18 13:27:02 +02:00
Thomas Haller
0e9e35e309 all: refactor hashing by introducing NMHashState
The privious NM_HASH_* macros directly operated on a guint value
and were thus close to the actual implementation.

Replace them by adding a NMHashState struct and accessors to
update the hash state. This hides the implementation better
and would allow us to carry more state. For example, we could
switch to siphash24() transparently.

For now, we still do a form basically djb2 hashing, albeit with
differing start seed.

Also add nm_hash_str() and nm_str_hash():

- nm_hash_str() is our own string hashing implementation

- nm_str_hash() is our own string implementation, but with a
  GHashFunc signature, suitable to pass it to g_hash_table_new().
  Also, it has this name in order to remind you of g_str_hash(),
  which it is replacing.
2017-10-18 13:05:00 +02:00
Thomas Haller
e71f7775a7 platform: fix comparing parent_ifindex in nm_platform_lnk_macsec_cmp() 2017-10-17 15:04:49 +02:00
Thomas Haller
4a2798434e core: introduce NM_HASH_INIT() to initialize hash seed
Introduce a NM_HASH_INIT() function. It makes the places
where we initialize a hash with a certain seed visually clear.

Also, move them from "shared/nm-utils/nm-shared-utils.h" to
"shared/nm-utils/nm-macros-internal.h". We might want to
have NM_HASH_INIT() non-inline (hence, define it in the
source file).
2017-10-13 12:47:55 +02:00
Thomas Haller
37ffc8bae9 platform: support pref option for IPv6 routes (RTA_PREF)
Support IPv6 router preference (RFC4191) in platform code.
2017-10-12 10:38:19 +02:00
Thomas Haller
5b0745e7bd platform: refactor detecting kernel support
We are going to add another parameter to check. Instead of adding multiple
virtual functions, add a NMPlatformKernelSupportFlags flags enum.
2017-10-12 10:38:19 +02:00
Thomas Haller
cc1ee1d286 all: rework configuring route table support by adding "route-table" setting
We added "ipv4.route-table-sync" and "ipv6.route-table-sync" to not change
behavior for users that configured policy routing outside of NetworkManager,
for example, via a dispatcher script. Users had to explicitly opt-in
for NetworkManager to fully manage all routing tables.

These settings were awkward. Replace them with new settings "ipv4.route-table"
and "ipv6.route-table". Note that this commit breaks API/ABI on the unstable
development branch by removing recently added API.

As before, a connection will have no route-table set by default. This
has the meaning that policy-routing is not enabled and only the main table
will be fully synced. Once the user sets a table, we recognize that and
NetworkManager manages all routing tables.

The new route-table setting has other important uses: analog to
"ipv4.route-metric", it is the default that applies to all routes.
Currently it only works for static routes, not DHCP, SLAAC,
default-route, etc. That will be implemented later.

For static routes, each route still can explicitly set a table, and
overwrite the per-connection setting in "ipv4.route-table" and
"ipv6.route-table".
2017-10-09 22:05:36 +02:00
Thomas Haller
dccf9f3a61 core: avoid compiler warnings related to cleanup attribute
gcc doesn't consider variables with cleanup attribute as unused.
clang does, and warns about them.

In one case, clang is right, in the other one the warning is bogus.

Fix both.
2017-10-05 14:47:38 +02:00
Thomas Haller
91be4c8c3d core: cleanup handling addr_family in NMDevice
- use nm_utils_addr_family_to_char(). It asserts that the input argument
  is either AF_INET or AF_INET6.
- rename variable @family to @addr_family for consistency.
- when logging addr_family for activation-stage, use v4 or v6 instead
  of numeric AF_INET/AF_INET6.
2017-10-02 13:56:00 +02:00
Thomas Haller
5b0f895e19 libnm,core: add TABLE attribute for routes settings
https://bugzilla.redhat.com/show_bug.cgi?id=1436531
2017-09-26 19:39:36 +02:00
Thomas Haller
7cd04ce014 core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.

It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().

Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-26 19:36:51 +02:00
Thomas Haller
9acf80a979 platform: handle route table RT_TABLE_UNSPEC specially
Kernel does not allow to add a route with table 0 (RT_TABLE_UNSPEC). It
effectively is an alias for the main table. We must consider that when
comparing routes sementically.
2017-09-26 19:31:17 +02:00
Thomas Haller
5819988ac7 platform: cleanup logging for adding link
No need for duplicate log lines

  <debug> [1506146476.8462] platform: link: adding tap tap0 owner 107 group -1
  <debug> [1506146476.8462] platform-linux: link: add tap tap0 owner 107 group -1

Merge them.

Also, for consistency change the logging output for adding generic
interfaces in nm_platform_link_add().
2017-09-25 14:49:44 +02:00
Thomas Haller
03e1cc96a5 core: fix handling IPv6 device-route and use correct route metric
Before commit 6698bf58bb, we would rely on
kernel to add the device-route for manual IPv6 routes. We broke that and now
kernel would still add the device-route, however nm_platform_ip_route_sync()
would delete it immediately after.
That is because previously nm_platform_ip_route_sync() would ignore routes
with rtm_protocol RTPRO_KERNEL. Now, it will sync and delete those too.

Fix that by adding the device-route like we do it for IPv4. This also
fixes an actual issue where the automatically added route always had
route-metric 256. Instead, we now use the metric from ipv6.route-metric
setting.

Fixes: 6698bf58bb
2017-09-19 11:49:29 +02:00
Thomas Haller
2cc1813340 core: workaround configuring IPv6 routes with "src" (RTA_PREFSRC)
Kernel does not allow to add IPv6 routes with "src", as long as the
corresponding address is still tentative (related bug rh#1457196).

The workaround for this is cumbersome. First, when we fail to add such a
route with "pref_src", we guess that it happend due to this issue. In
that case, nm_ip6_config_commit() returns the list of routes that could
not be added for the moment (but hopefully can be added later).

We track this list in NMDevice, and keep trying to merge the routes
back into ip6_config. In order to not try indefinitely, keep track of a
timestamp when we tried to add this route for the first time.

Another uglyness is that pending tentative routes don't explicitly block
activation. In practice they may do, because for these routes we also have
an IPv6 address that is still doing DAD, so the IP configuration is
still pending due to that.

https://bugzilla.redhat.com/show_bug.cgi?id=1452684
2017-09-15 17:28:48 +02:00
Thomas Haller
6698bf58bb core: track routes with source RTPROT_KERNEL (rtm_protocol) in NMIP4Config/NMIP6Config
Let's not treat those routes special. I think this was originally done, because
we relied on kernel to add the IPv4 device route, so we would ignore RTPROT_KERNEL
routes and not delete them.

We want to track them for various reasons:

 - for consistency, there is nothing special except that they might be
   added by kernel.
 - we expose the routes of NMIP4Config/NMIP6Config on D-Bus. That should
   include also routes such as device routes. Note, this commit changes
   that we now expose device routes on D-Bus too.
2017-09-13 08:17:31 +02:00
Thomas Haller
aee48dfd44 core: adjust route equality for NMIP4Config/NMIP6Config to what kernel does
For kernel, route ID compare identical according to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID.
Well, mostly. In practice, NM ignores several route properties that
kernel considers part of the ID too. This leaves the possibility that
kernel allows addition of two routes that compare idential for
NetworkManager.

Anyway, NMIP4Config/NMIP6Config should use the same equality as platform
cache. Otherwise, there is the odd situation that ip-config merges routes
that are treated as different by kernel.

For IP addresses the ID operator already corresponded to what kernel
does. There is no change for addresses.

Note that NMSettingIPConfig also uses a different algorithm for
comparing routes. But that doesn't really matter here, it it differed
before too.
2017-09-13 08:17:31 +02:00
Thomas Haller
77ec302714 core: rework handling of default-routes and drop NMDefaultRouteManager
Remove NMDefaultRouteManager. Instead, add the default-route to the
NMIP4Config/NMIP6Config instance.

This basically reverts commit e8824f6a52.
We added NMDefaultRouteManager because we used the corresponding to `ip
route replace` when configuring routes. That would replace default-routes
on other interfaces so we needed a central manager to coordinate routes.
Now, we use the corresponding of `ip route append` to configure routes,
and each interface can configure routes indepdentently.

In NMDevice, when creating the default-route, ignore @auto_method for
external devices. We shall not touch these devices.

Especially the code in NMPolicy regarding selection of the best-device
seems wrong. It probably needs further adjustments in the future.
Especially get_best_ip_config() should be replaced, because this
distinction VPN vs. devices seems wrong to me.
Thereby, remove the @ignore_never_default argument. It was added by
commit bb75026004, I don't think it's
needed anymore.

This brings another change. Now that we track default-routes in
NMIP4Config/NMIP6Config, they are also exposed on D-Bus like regular
routes. I think that makes sense, but it is a change in behavior, as
previously such routes were not exposed there.
2017-09-08 11:11:21 +02:00
Thomas Haller
e805201f4b platform: delete routes after adding in nm_platform_ip_route_sync()
Previously, we would first delete routes that are not to be added,
before adding the new ones.

This has the advantage, that even if delete removes the wrong route,
add would restore the expected state. This tries to workaround the fact
that RTM_DELROUTE allows for wild-card fields, and might delete the
wrong route.

However, for example when bumping the route metric after connectivty
check (removing the default-route with metric 20100 and adding the one
with metric 100), there is a short moment when there is no
default-route.

To avoid that, don't do delete-then-add, but add-then-delete.
2017-09-08 11:05:05 +02:00
Thomas Haller
b3254da173 platform/trivial: add code comments 2017-09-08 11:05:04 +02:00
Thomas Haller
7046ce5332 platform: add oif argument to nm_platform_ip_route_get()
Analog to `ip route get $DST oif $IFACE`.
2017-09-07 11:14:27 +02:00