Commit graph

280 commits

Author SHA1 Message Date
Thomas Haller
d7ebbd69a0 core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.

However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.

We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.

Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).

Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.

(cherry picked from commit c03a534963)
2018-10-19 18:39:33 +02:00
Lubomir Rintel
f7df4f0cde 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.

(cherry picked from commit 93ac0e455b)
2017-12-11 18:56:41 +01:00
Beniamino Galvani
ba630b828b core: don't reset existing routes when merging IP setting
Don't reset existing routes if ipvx.ignore-auto-routes=yes: callers
should already avoid adding them when not needed.

Previously we would also reset the manual gateway route just added.

Fixes: 5c299454b4

https://bugzilla.gnome.org/show_bug.cgi?id=790423
(cherry picked from commit a0cd75b20c)
2017-11-17 13:44:47 +01:00
Thomas Haller
4b890dead5 all: support route-attribute "onlink" for IPv4
Kernel doesn't support it for IPv6.

This is especially useful, if you combine static routes
with DHCP. In that case, you might want to get the device-route
to the gateway automatically, but add a static-route for it.

(cherry picked from commit 0ed49717ab)
2017-11-13 14:43:07 +01:00
Thomas Haller
f0bcf533f5 core: merge IPv4 and IPv6 version of _nm_ip_config_merge_route_attributes()
(cherry picked from commit 433d2f8659)
2017-11-13 14:43:07 +01:00
Thomas Haller
5a9812f453 core: add NMIPConfig helpers
For now, hack some generic accessors to the NMIP4Config/NMIP6Config
type. Eventually, NMIP4Config and NMIP6Config should get merged in
one class.

(cherry picked from commit 9e25538ff5)
2017-11-13 14:40:31 +01: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
Beniamino Galvani
31ad3dbc96 core: fix memory leaks in NMIP{4,6}Config
Fixes: 03e1cc96a5
Fixes: 9a3117f1d3
2017-10-10 09:52:39 +02:00
Thomas Haller
5c299454b4 core: rework tracking of gateway/default-route in ip-config
Instead of having 3 properties @gateway, @never_default and @has_gateway
on NMIP4Config/NMIP6Config that determine the default-route, track the
default-route as a regular route.

The gateway setting is the configuration knob for the default-route.
Since an NMIP4Config/NMIP6Config instance only has one gateway property,
it cannot track more then one default-routes (see related bug rh#1445417).
Especially with policy routing, it might be interesting to configure a
default-route in multiple tables.

Also, later it might be interesting to allow adding default-routes as
regular static routes in a connection, so that the user can configure additional
route parameters for the default-route or add default-routes in multiple tables.

With this patch, default-routes now have a rt_source property according to their
origin.

Also, the previous commits of this branch broke handling of the
default-route :) . That should be working now again.
2017-10-10 08:46:47 +02:00
Thomas Haller
2bdfc092d4 core: don't track route metric in ip-config
It's not needed. Whenever we add a route, we pass in the
route metric (for example, based on the device's configuration).
No need to merge and track it into the NMIP4Config/NMIP6Config.

The metric was only used in nm_ip4_config_create_setting()
and nm_ip6_config_create_setting(). In fact it's wrong to do
that, because it means we first capture some settings, and guess
the configured route metric. But we cannot do that. Our best
guess what a configured setting might be is -1.
2017-10-09 22:06:25 +02:00
Thomas Haller
9003dae6cd core: don't track route MSS in ip-config
The MSS is only set for VPN connections (by merging it in the respective
NMIP4Config/NMIP6Config).

It is also only used when setting the MSS of the default route.

Don't track that property in NMIP4Config/NMIP6Config, instead, set the
mss of the route directly in nm_vpn_connection_ip4_config_get() and
nm_vpn_connection_ip6_config_get().

There is a potential change in behavior here: NMDevice also consisdered
the MSS for the default route, but that would only be set if the MSS
gets merged from an vpn-ip-config. Which at most is the case for
iterface-less VPN types (libreswan). But even in that case, it doesn't
seem right to me to use the VPN's MSS for the device's default-route.
2017-10-09 22:06:25 +02:00
Thomas Haller
01930c96b8 core: use ipv4.route-table setting for other IPv4 routes
Including device-routes, default-route, DHCPv4, IPv4LL.
2017-10-09 22:06:25 +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
8f1ef161f4 core: refactor parsing resolve.conf
- merge the IPv4 and IPv6 implementations. They are for the most
  part identical. Also, they are independent of NMIP4Config/NMIP6Config.

- parse the entire file at once. Don't parse it twice, once for the
  name servers and once for the options. This also avoids loading
  /etc/resolv.conf twice, as it would be done before.
2017-10-09 22:05:35 +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
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
9a3117f1d3 core: track IPv4 device routes in NMIP4Config
For IPv6, we create device routes when processing the RA and add it to
NMIP6Config like any other route. For IPv4 we didn't do that. Instead
we created the list of device routes during nm_ip4_config_commit() and
passed it to nm_platform_ip_route_sync().
2017-09-13 08:17:31 +02:00
Thomas Haller
4b4efac3ab core: fix merging IP addresses in NMIP4Config/NMIP6Config
When merging IP addresses, we keep the best addr_source and the internally
configured timestamps. Since the check for the timestamp considers addr_source,
we must move the check before merging addr_source.
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
eb948e793e core: fix invalid assertion in nm_ip4_config_get_num_routes()
Fixes: 935411e5c0
2017-09-13 08:17:30 +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
0918b4914d core: support tracking default-route in NMIP4Config/NMIP6Config
Default-routes are for the most part like regular routes. Add support to
track them like regular routes in NMIP4Config/NMIP6Config.

One thing is, sometimes we need to figure out whether an ip-config
instance has a default-route. For that, keep track of the best
default-route (there might be multiple) and expose it. That is
the most complicated part of this patch, because there are so many
places where the list of routes gets modified (replace, intersect,
subtract, merge, add), and they all need to take care of updating
the best default-route.

In a next patch, NMDefaultRouteManager will be dropped and default-routes
will be tracked by NMIP4Config/NMIP6Config.
2017-09-08 11:11:21 +02:00
Thomas Haller
96f1358eef core: return new route from _nm_ip_config_add_obj()
Later we will need the exact instance that we just added (or the previously
existing one, if the new route is already tracked).
2017-09-08 11:05:05 +02:00
Thomas Haller
ead1ffd9bc core/trivial: rename test functions _nmtst_nm_ip*_config_*() to _nmtst_ip*_config_*() 2017-09-08 11:05:05 +02:00
Thomas Haller
7ab40b9e10 core: ignore routes from non-main table in nm_ip4_config_capture()
and nm_ip6_config_capture().
2017-09-08 11:05:05 +02:00
Thomas Haller
199499967a core: don't loop twice over routes in nm_ip4_config_capture()
and nm_ip6_config_capture().
2017-09-08 11:05:05 +02:00
Thomas Haller
a0ca607080 core: return new object from _nm_ip_config_add_obj()
Will be used later.
2017-09-08 11:05:04 +02:00
Thomas Haller
546e12417a core: use _nm_ip_config_add_obj() in nm_ip4_config_replace() for routes
Avoid calling nm_dedup_multi_index_add() directly, like we do for all other places.
Instead, call the wrapper _nm_ip_config_add_obj() which does some pre-precessing.

In practice, the result is exactly the same (at the moment). But there should by
only one way to add the route.
2017-09-08 11:05:04 +02:00
Thomas Haller
5c42cdb287 all: use _nm_utils_ip4_*() utils functions 2017-09-05 18:44:04 +02:00
Thomas Haller
4adda2b79a core: fix clearing dirty flag in _nm_ip_config_add_obj()
We rely on clearing the dirty flag. For example in nm_ip4_config_replace(),
we first mark all entries dirty, then force-append the ones we keep,
and finally remove the ones that are still dirty.

Since _nm_ip_config_add_obj() short-cuts nm_dedup_multi_index_add_full(),
it must clear the dirty flag on its own.
2017-08-31 13:13:24 +02:00
Thomas Haller
44917a910a core: use _nm_ip_config_add_obj() in NMIP4Config/NMIP6Config 2017-08-30 18:59:36 +02:00
Thomas Haller
eba646ec42 core: fix emitting changed notification during nm_ip4_config_intersect() 2017-08-30 11:47:34 +02:00
Thomas Haller
d95df1cef0 core/trivial: rename local variable
For consistency with other places.
2017-08-30 11:47:34 +02:00
Thomas Haller
e470e13922 core: don't suppress host route to gateway in ip-config caputure
Why would we do this? The route is there, so, add it.
This revises commit 4fba2260f3
which added this check for matching generated connections.
I don't think this is still necessary, and if it is, then
the matching should be relaxed instead. It's bad to hide
routes from NMIP4Config/NMIP6Config, because those routes are
also exported via D-Bus.
2017-08-24 11:03:45 +02:00
Thomas Haller
10ac675299 platform: add support for routing tables to platform cache
The upper layers still ignore all routes outside the main table.
For now, just add support to NMPlatform.
2017-08-24 10:55:51 +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
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
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
20235453a9 core: fix crash in nm_ip4_config_address_exists()
Fixes: 22edeb5b69
2017-08-23 18:37:21 +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
9be9cab646 core: implement NMIP4Config's and NMIP6Config's route equality based on nm_platform_ipx_route_cmp()
There are various notions of how to compare routes. Collect them all
in nm_platform_ip4_route_cmp(), nm_platform_ip4_route_hash(),
nm_platform_ip6_route_cmp(), and nm_platform_ip6_route_hash().

This way, we have them side-by-side, which makes the differences more
discoverable.
2017-08-03 18:51:35 +02:00
Thomas Haller
372f14a6ef platform: add compare functions for routes with different compare semantics
Routes are complicated.

`ip route add` and `ip route append` behaves differently with respect to
determine whether an existing route is idential or not.

Extend the cmp() and hash() functions to have a compare type, that
covers the different semantics.
2017-08-03 18:32:59 +02:00
Beniamino Galvani
24b8429ee3 core: emit notify signals for addresses/routes in nm_ipX_config_replace
Fixes: 22edeb5b69
Fixes: 935411e5c0
Fixes: cfd1851c00
2017-07-25 14:49:50 +02:00
Thomas Haller
5f99512366 core: prevent invalid routes in NMIP4Config/NMIP6Config
Kernel requires that the host part of a route (based on network/plen)
is zero. Routes with non-zero host part don't really exist.

In settings (NMIPRoute), we don't enforce that. Hence we must ensure
that we don't let such invalid routes into NMIP4Config/NMIP6Config.

Also at other places where we obtain routes from untrusted sources,
we must sanitize them first.

Also add an assertion to catch such bugs.
2017-07-25 06:44:13 +02:00
Thomas Haller
4057a31017 core: simplify NMDedupMultiIter by storing CList pointer
Let next and head pointers point to the CList value, instead of
NMDedupMultiEntry.
2017-07-25 06:44:12 +02:00
Thomas Haller
5fcca9ba3e platform: refactor nm_platform_ip4_address_sync()
To reuse array of NMPObject instances instead of creating
a GArray clone.

Also get rid of the nm_platform_ipx_address_get_all() functions.
2017-07-25 06:44:12 +02:00