diff options
author | Thomas Haller <thaller@redhat.com> | 2017-08-02 07:55:05 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-08-11 18:12:03 +0200 |
commit | b325fdd080744210eb6759055297970626338e9d (patch) | |
tree | bce1fc3ab540300218f72749e5d92ce033be5e88 | |
parent | f3750f1126ec6fc95413415b351eedb8af73c78e (diff) | |
download | NetworkManager-th/platform-route-pt2.tar.gz |
WIP: platform: drop route-managerth/platform-route-pt2
Previously, we would always add routes with netlink message flags
NLM_F_CREATE | NLM_F_REPLACE, akin `ip route replace`.
Using this 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. Only one of the routes can be actually configured
using `ip route replace`, so we need to track routes that are
currently shaddowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces.
That was worked around by introducing NMRouteManager (and
NMDefaultRouteManager). NMRouteManager would keep a list of the routes
that NetworkManager would like to configure, even if momentarily being
unable to do so due to conflicting routes. This worked mostly well but
was rather complicated, involving bumping metrics (to avoid conflicts
for device routes that were required to configure gateway routes).
Drop that now. Use the corresponding of `ip route append` to configure
routes. This allows NM to confiure (almost) all routes that it cares.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence,
NMRouteManager becomes mostly obsolete.
This 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 using IFA_F_NOPREFIXROUTE flag for addresses
(still to-do). But as kernel may not support that flag for IPv4 addresses yet, we still
need functionality like nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality now moves to NMDevice, which tracks a blacklist of device routes
that shall be removed.
- 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 keeps the list of routes that 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 also
keep track of routes that the device would like to configure, but currently cannot (due
to conflicting routes on other devices).
We want to get rid of that. However, with IPv6 routes with source addresses, we cannot.
The tracking of such routes, that the device wants to configure, but currently cannot,
also goes to NMDevice.
-rw-r--r-- | src/platform/nm-platform.c | 34 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 5 |
2 files changed, 39 insertions, 0 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 4f0ab9ac44..9cc2e15d05 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3451,6 +3451,40 @@ nm_platform_address_flush (NMPlatform *self, int ifindex) && nm_platform_ip6_address_sync (self, ifindex, NULL, FALSE); } +void +nm_platform_ip_route_sync (NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray *routes) +{ + guint i; + gs_unref_ptrarray GPtrArray *plat_routes = NULL; + + nm_assert (NM_IS_PLATFORM (self)); + nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + nm_assert (ifindex > 0); + nm_assert ( !routes + || ({ + gboolean valid = TRUE; + for (i = 0; i < routes->len; i++) { + NMPObjectType t = NMP_OBJECT_GET_TYPE (routes->pdata[i]); + if (addr_family == AF_INET) + valid &= (t == NMP_OBJECT_TYPE_IP4_ROUTE); + else + valid &= (t == NMP_OBJECT_TYPE_IP4_ROUTE); + } + valid; + })); + + plat_routes = nm_platform_lookup_addrroute_clone (self, + addr_family == AF_INET + ? NMP_OBJECT_TYPE_IP4_ROUTE + : NMP_OBJECT_TYPE_IP6_ROUTE, + ifindex, + NULL, + NULL); +} + /*****************************************************************************/ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_nmp_nlm_flag_to_string_lookup, NMPNlmFlags, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 841c5e77a7..dcb082d927 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -1102,6 +1102,11 @@ gboolean nm_platform_ip6_route_add (NMPlatform *self, NMPNlmFlags flags, const N gboolean nm_platform_ip_route_delete (NMPlatform *self, const NMPObject *route); +void nm_platform_ip_route_sync (NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray *routes); + const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len); const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len); const char *nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len); |