Commit graph

26 commits

Author SHA1 Message Date
Thomas Haller
eecc440351 core: use NM_DEFINE_SINGLETON_GETTER() macro 2015-01-12 12:10:03 +01:00
Thomas Haller
822cb293ef core/trivial: rename singleton variables according to default name 2015-01-12 12:10:02 +01:00
Thomas Haller
0b50940f43 platform: add paramter to ip4_route_add to set src (RTA_PREFSRC)
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-25 22:30:38 +01:00
Thomas Haller
a0f81f266b policy: enforce absence of default route on never-default VPN connections
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:33 +01:00
Thomas Haller
308a5e7953 policy: fix handling managed devices without default route
Before, we would only track a device in NMDefaultRouteManager
if it had a default route. Otherwise the entry for the device
was removed.

That was wrong, because having no entry meant that the interface
is assumed and hence we would not touch the interface. Instead we must
esplicitly track devices without default route to know when an interface
has no default route.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:33 +01:00
Thomas Haller
815e67a61f policy: sort default routes by metrics before adding them
It's better to add the more important routes first. Otherwise there
might be a short time when a lower priority route has precedence.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
1f5f576c33 policy: pick up externally configured default routes for managed interfaces
The previous commit made NM enforce the default route on interfaces for
which NM manages a default route.

For interfaces that are configured never-default, NM will now pick up
any externally configured default route, as if it was managed by NM.
This is important, because NMDefaultRouteManager needs a notion of which
is the best device. Without this change, it was agnostic to default routes
on managed, never-default interfaces.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
16b0ddb66d policy: resync routes on platform change events
Monitor default routes from platform, and resync the default routes
on changes.

For one, this fixes the following use-case: have an assumed device em1
with two routes of metric 20 and 21. Activate em2, which will get effective
metric 22.
When externally removing route em1/20, em2 would resync the effective metric to
20. This is correct and already worked before. However, when deleting em1/21,
nothing happened. With this change, em2 would resync to metric 21 to fill the gap.

However this commit has much bigger effects: whenever the user externally adds
a default route to an interface for which NM manages an default route, NM will
delete it.
Also, when deleting the default route (managed by NM), NM would readd
it. Effectivly, the user can no longer mess with the default route on
interfaces for which it manages the default route.

If the connection is configured never-default, the user still can add
default routes and NM will not touch them.

Obviously, this has no effect for assumed devices either and the user
can externally add and remove default routes as he wishes.

https://bugzilla.gnome.org/show_bug.cgi?id=735512

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
b4b67c47f1 policy: consider additional assumed routes when synchronizing the default route
Don't only consider the best route of assumed devices when syncing the route
metrics. This fixes the following scenario:

Have em1 assumed, with two default routes (metric 20 and 21).
When activating em2, NMDefaultRouteManager would  have determined
21 as the effective metric, thus replacing the assumed route of em1.

Since we don't want to touch assumed interfaces, it is wrong to
replace their default routes.

Instead, keep track of all the assumed default routes and consider their
metrics when choosing effective_metric.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
6d4bb29781 policy: minor refactoring in NMDefaultRouteManager to access routes generically
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
462456f255 policy: remove redundant remove_default_route() functions from NMDefaultRouteManager
When calling update_default_route(), NMDefaultRouteManager will look at the
source, and determine whether it has a default route or not. For example
for device sources, this means calling nm_device_get_ip4_default_route().

If the source indicates that it has no default route, the effect of
calling update_default_route() is the same as calling
remove_default_route() (hence, remove() can be replaced by update()).

If the source however still indicates a default route, the behavior
would be different. This case would be an undesired inconsistancy,
because source and NMDefaultRouteManager would disagree of whether
the source has a default route.
Source must always properly indicate whether it has a default route
or not, hence this situation does not arise.

Hence it is always better to call update().

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
393f213c3b policy: remove unused @do_sync argument from NMDefaultRouteManager functions
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
825885d5b1 policy: minor fix when having multiple default routes with metric MAXUINT32
The case of having a metric MAXUINT32 is special, because in face of
multiple default routes with the same metric, NMDefaultRouteManager
cannot reduce the effective metric (because there is no lower priority
value).

This case works already correct, just when adding such a default route,
ensure that we add it to the *first* entry.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:32 +01:00
Thomas Haller
a43ed6cb80 policy: refactor NMDefaultRouteManager to use union type NMPlatformIPXRoute
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-19 22:55:31 +01:00
Dan Winship
3bfb163a74 all: consistently include config.h
config.h should be included from every .c file, and it should be
included before any other include. Fix that.

(As a side effect of how I did this, this also changes us to
consistently use "config.h" rather than <config.h>. To the extent that
it matters [which is not much], quotes are more correct anyway, since
we're talking about a file in our own build tree, not a system
include.)
2014-11-13 17:18:42 -05:00
Dan Williams
12f2f09e55 core: remove unused variable 2014-11-11 17:28:50 -06:00
Thomas Haller
ee0c1cf0bd policy: fix using wrong loop counter in _platform_route_sync_flush()
Fixes: e8824f6a52
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-10 12:30:39 +01:00
Thomas Haller
065a3240fb policy: fix get_best_device() to return only active devices from the list
This fixes an assertion during shutdown. NMManager:dispose()
calls remove_device(), which eventually hit the assertion
in nm_default_route_manager_ip4_get_best_device().

Remove the assertion, but also make sure that the function only
returns devices from the provided list. It is counter intuitive,
that the function might return devices that are not in the provided
list.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 18:50:31 +01:00
Thomas Haller
6e409ef91f policy: return best config based on the internal sorting of NMDefaultRouteManager
Now that both VPN and devices are managed (and ordered) by
NMDefaultRouteManager, refactor get_best_config() to use the
priority accordingly.

Before, we would first iterate over all VPN connections and
returning the best one. Only if no suitable VPN connection
was found, a best device would be returned.
Modify get_best_config() to treat VPN and device the same and
return the best one based on the route metric.

With this change, get_best_config() gives consistent results
together with get_best_device(). Also, you can configure
that a device gets a higher priority then a VPN.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
f22c72d299 policy: improve get_best_device() to strictly adhering the sort order of the entries
get_best_device() has two different modes depending on the @fully_activated argument.
If @fully_activated, it only considers devices that are considered as active.
Otherwise, it returns the best activating device (if that device is expected
to be better then any of the already activated devices).

Before, the check whether an activated device is considered best device
also involved looking at the device state. This redundancy was harmful
because part of NMDefaultRouteManager considered a device as fully activated,
but get_best_device() might not return them.

Split get_best_device() in two parts. The one part _ipx_get_best_activating_device()
now checks for still activating devices. When inspecting devices with
an entry, those devices are weighted according to _ipx_get_best_device().
That means that both functions now give a consistent result.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
eb61cdc6c5 policy: set default routes for VPN via NMDefaultRouteManager
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
ff40ccf899 policy: move get_best_config() function to nm-default-route-manager
No functional change, only refactoring by moving and combining the code.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
a39a3ae4cd policy: track default route for VPN in NMDefaultRouteManager
Extend NMDefaultRouteManager to track NMVpnConnection beside
NMDevice. That way, all default routes are managed by
NMDefaultRouteManager.

For VPN connections the manager also tracks connections that are
set never_default. That is useful because NMPolicy still uses VPNs
without default route to setup DNS. Hence, NMDefaultRouteManager
trackes those connections to have the relative priority of the
devices.
Interestingly, that means that for VPNs that are ipv4.never-default,
ipv4.route-metric still has an effect in determining relative priorities
for DNS configuration.

This commit only adds the parts to track the default route. NMPolicy
still sets the route as before.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
a94605f92b policy: better sync get_best_device() with NMDefaultRouteManager
NMDefaultRouteManager has a sorted list of routes. Change get_best_device()
to better consider that list when choosing a best device.

Always prefer the priority as reported from entry->effective_metric
if the device is registered to have a default route. Before for
!fully_activated, we choose the metric based on
nm_device_get_ipx_route_metric().

Add more checks in case of equal priority. For @fully_activated,
always prefer the device that is sorted by NMDefaultRouteManager.
For non @fully_activated, prefer the device with an entry.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
0fc47f3b57 policy: move get_best_device() function to nm-default-route-manager
No functional change, only refactoring by moving and combining the code.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00
Thomas Haller
e8824f6a52 policy: add manager for default routes and support multiple default routes
Up to now, NMPolicy would iterate over all devices to find the "best"
device and assign the default route to that device.

A better approach is to add a default route to *all* devices that
are never-default=no. The relative priority is choosen according to
the route metrics.

If two devices receive the same metric, we want to prefer the device
that activates first. That way, the default route sticks to the same
device until a better device activates or the device deactivates.
Hence, the order of activation is imporant in this case (as it is
already now).

Also, if several devices have identical metrics, increment their
metrics so that every metric is unique.
This makes the routing deterministic according to what we choose as best
device.

A special case is assumed devices. In this case we cannot adjust the metric
in face of equal metrics.

Add a new singleton class NMDefaultRouteManager that has a list of all
devices and their default routes. The manager will order the devices by
their priority and configure the routes using platform.

Also update the metric for VPN connections. Later we will track VPN
routes also via NMDefaultRouteManager. For now, fix the VPN metric because
otherwise VPNs would always get metric 1024 (which is usually much larger then the
device metrics).

https://bugzilla.gnome.org/show_bug.cgi?id=735512

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-11-07 15:23:12 +01:00