mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 19:20:12 +01:00
core: split route management code out from platform
Create a NMRouteManager singleton.
Refactor, no functional changes apart from change of log domain from
LOGD_PLATFORM to LOGD_CORE.
Subsequent commit will keep track of the conflicting routes, avoid overwriting
older ones with newer ones and apply the new ones when the old ones go away.
(cherry picked from commit 874e4a7595)
This commit is contained in:
parent
f45bd84433
commit
af36a41440
11 changed files with 311 additions and 209 deletions
|
|
@ -300,6 +300,8 @@ nm_sources = \
|
|||
nm-dbus-manager.h \
|
||||
nm-dcb.c \
|
||||
nm-dcb.h \
|
||||
nm-route-manager.c \
|
||||
nm-route-manager.h \
|
||||
nm-default-route-manager.c \
|
||||
nm-default-route-manager.h \
|
||||
nm-dhcp4-config.c \
|
||||
|
|
@ -498,6 +500,9 @@ libnm_iface_helper_la_SOURCES = \
|
|||
rdisc/nm-rdisc.c \
|
||||
rdisc/nm-rdisc.h \
|
||||
\
|
||||
nm-route-manager.c \
|
||||
nm-route-manager.h \
|
||||
\
|
||||
nm-ip4-config.c \
|
||||
nm-ip4-config.h \
|
||||
nm-ip6-config.c \
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include "nm-dns-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "nm-route-manager.h"
|
||||
|
||||
#include "nm-device-logging.h"
|
||||
_LOG_DECLARE_SELF (NMDevice);
|
||||
|
|
@ -7758,7 +7759,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, gboolean deconfig
|
|||
/* Take out any entries in the routing table and any IP address the device had. */
|
||||
ifindex = nm_device_get_ip_ifindex (self);
|
||||
if (ifindex > 0) {
|
||||
nm_platform_route_flush (NM_PLATFORM_GET, ifindex);
|
||||
nm_route_manager_route_flush (nm_route_manager_get (), ifindex);
|
||||
nm_platform_address_flush (NM_PLATFORM_GET, ifindex);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "nm-device-private.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-modem-enum-types.h"
|
||||
#include "nm-route-manager.h"
|
||||
|
||||
G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT)
|
||||
|
||||
|
|
@ -912,7 +913,7 @@ deactivate_cleanup (NMModem *self, NMDevice *device)
|
|||
priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) {
|
||||
ifindex = nm_device_get_ip_ifindex (device);
|
||||
if (ifindex > 0) {
|
||||
nm_platform_route_flush (NM_PLATFORM_GET, ifindex);
|
||||
nm_route_manager_route_flush (nm_route_manager_get (), ifindex);
|
||||
nm_platform_address_flush (NM_PLATFORM_GET, ifindex);
|
||||
nm_platform_link_set_down (NM_PLATFORM_GET, ifindex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "nm-ip4-config-glue.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-route-manager.h"
|
||||
|
||||
G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT)
|
||||
|
||||
|
|
@ -282,7 +283,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, guint32 default_ro
|
|||
g_array_append_vals (routes, route, 1);
|
||||
}
|
||||
|
||||
success = nm_platform_ip4_route_sync (NM_PLATFORM_GET, ifindex, routes);
|
||||
success = nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes);
|
||||
g_array_unref (routes);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "nm-dbus-manager.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-ip6-config-glue.h"
|
||||
#include "nm-route-manager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, G_TYPE_OBJECT)
|
||||
|
|
@ -396,7 +397,7 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex)
|
|||
g_array_append_vals (routes, route, 1);
|
||||
}
|
||||
|
||||
success = nm_platform_ip6_route_sync (NM_PLATFORM_GET, ifindex, routes);
|
||||
success = nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes);
|
||||
g_array_unref (routes);
|
||||
}
|
||||
|
||||
|
|
|
|||
244
src/nm-route-manager.c
Normal file
244
src/nm-route-manager.c
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-route-manager.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
G_DEFINE_TYPE (NMRouteManager, nm_route_manager, G_TYPE_OBJECT)
|
||||
|
||||
static NMRouteManager *_instance;
|
||||
|
||||
static gboolean
|
||||
array_contains_ip4_route (const GArray *routes, const NMPlatformIP4Route *route)
|
||||
{
|
||||
guint len = routes ? routes->len : 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
NMPlatformIP4Route *c = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (route->network == c->network &&
|
||||
route->plen == c->plen &&
|
||||
route->gateway == c->gateway &&
|
||||
route->metric == c->metric)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
array_contains_ip6_route (const GArray *routes, const NMPlatformIP6Route *route)
|
||||
{
|
||||
guint len = routes ? routes->len : 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
NMPlatformIP6Route *c = &g_array_index (routes, NMPlatformIP6Route, i);
|
||||
|
||||
if (IN6_ARE_ADDR_EQUAL (&route->network, &c->network) &&
|
||||
route->plen == c->plen &&
|
||||
IN6_ARE_ADDR_EQUAL (&route->gateway, &c->gateway) &&
|
||||
route->metric == c->metric)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nm_route_manager_ip4_route_sync:
|
||||
* @ifindex: Interface index
|
||||
* @known_routes: List of routes
|
||||
*
|
||||
* A convenience function to synchronize routes for a specific interface
|
||||
* with the least possible disturbance. It simply removes routes that are
|
||||
* not listed and adds routes that are.
|
||||
* Default routes are ignored (both in @known_routes and those already
|
||||
* configured on the device).
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes)
|
||||
{
|
||||
GArray *routes;
|
||||
NMPlatformIP4Route *route;
|
||||
const NMPlatformIP4Route *known_route;
|
||||
gboolean success;
|
||||
int i, i_type;
|
||||
|
||||
/* Delete unknown routes */
|
||||
routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT);
|
||||
for (i = 0; i < routes->len; i++) {
|
||||
route = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (!array_contains_ip4_route (known_routes, route))
|
||||
(void) nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, route->network, route->plen, route->metric);
|
||||
}
|
||||
|
||||
if (!known_routes) {
|
||||
g_array_free (routes, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add missing routes */
|
||||
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
|
||||
for (i = 0; i < known_routes->len && success; i++) {
|
||||
known_route = &g_array_index (known_routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route))
|
||||
continue;
|
||||
|
||||
if ((known_route->gateway == 0) ^ (i_type == 0)) {
|
||||
/* Make two runs over the list of routes. On the first, only add
|
||||
* device routes, on the second the others (gateway routes). */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore routes that already exist */
|
||||
if (!array_contains_ip4_route (routes, known_route)) {
|
||||
success = nm_platform_ip4_route_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
known_route->source,
|
||||
known_route->network,
|
||||
known_route->plen,
|
||||
known_route->gateway,
|
||||
0,
|
||||
known_route->metric,
|
||||
known_route->mss);
|
||||
if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) {
|
||||
nm_log_dbg (LOGD_CORE, "ignore error adding IPv4 route to kernel: %s",
|
||||
nm_platform_ip4_route_to_string (known_route));
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (routes, TRUE);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_route_manager_ip6_route_sync:
|
||||
* @ifindex: Interface index
|
||||
* @known_routes: List of routes
|
||||
*
|
||||
* A convenience function to synchronize routes for a specific interface
|
||||
* with the least possible disturbance. It simply removes routes that are
|
||||
* not listed and adds routes that are.
|
||||
* Default routes are ignored (both in @known_routes and those already
|
||||
* configured on the device).
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes)
|
||||
{
|
||||
GArray *routes;
|
||||
NMPlatformIP6Route *route;
|
||||
const NMPlatformIP6Route *known_route;
|
||||
gboolean success;
|
||||
int i, i_type;
|
||||
|
||||
/* Delete unknown routes */
|
||||
routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT);
|
||||
for (i = 0; i < routes->len; i++) {
|
||||
route = &g_array_index (routes, NMPlatformIP6Route, i);
|
||||
route->ifindex = 0;
|
||||
|
||||
if (!array_contains_ip6_route (known_routes, route))
|
||||
nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, route->network, route->plen, route->metric);
|
||||
}
|
||||
|
||||
if (!known_routes) {
|
||||
g_array_free (routes, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add missing routes */
|
||||
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
|
||||
for (i = 0; i < known_routes->len && success; i++) {
|
||||
known_route = &g_array_index (known_routes, NMPlatformIP6Route, i);
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route))
|
||||
continue;
|
||||
|
||||
if (IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway) ^ (i_type == 0)) {
|
||||
/* Make two runs over the list of routes. On the first, only add
|
||||
* device routes, on the second the others (gateway routes). */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore routes that already exist */
|
||||
if (!array_contains_ip6_route (routes, known_route)) {
|
||||
success = nm_platform_ip6_route_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
known_route->source,
|
||||
known_route->network,
|
||||
known_route->plen,
|
||||
known_route->gateway,
|
||||
known_route->metric,
|
||||
known_route->mss);
|
||||
if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) {
|
||||
nm_log_dbg (LOGD_CORE, "ignore error adding IPv6 route to kernel: %s",
|
||||
nm_platform_ip6_route_to_string (known_route));
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (routes, TRUE);
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_route_manager_route_flush (NMRouteManager *self, int ifindex)
|
||||
{
|
||||
return nm_route_manager_ip4_route_sync (self, ifindex, NULL)
|
||||
&& nm_route_manager_ip6_route_sync (self, ifindex, NULL);
|
||||
}
|
||||
|
||||
NMRouteManager *
|
||||
nm_route_manager_get ()
|
||||
{
|
||||
if (G_UNLIKELY (!_instance)) {
|
||||
_instance = NM_ROUTE_MANAGER (g_object_new (NM_TYPE_ROUTE_MANAGER, NULL));
|
||||
g_object_add_weak_pointer (G_OBJECT (_instance), (gpointer *) &_instance);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_route_manager_init (NMRouteManager *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nm_route_manager_class_init (NMRouteManagerClass *klass)
|
||||
{
|
||||
}
|
||||
51
src/nm-route-manager.h
Normal file
51
src/nm-route-manager.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-types.h"
|
||||
|
||||
#ifndef __NETWORKMANAGER_ROUTE_MANAGER_H__
|
||||
#define __NETWORKMANAGER_ROUTE_MANAGER_H__
|
||||
|
||||
#define NM_TYPE_ROUTE_MANAGER (nm_route_manager_get_type ())
|
||||
#define NM_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ROUTE_MANAGER, NMRouteManager))
|
||||
#define NM_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ROUTE_MANAGER, NMRouteManagerClass))
|
||||
#define NM_IS_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ROUTE_MANAGER))
|
||||
#define NM_IS_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ROUTE_MANAGER))
|
||||
#define NM_ROUTE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ROUTE_MANAGER, NMRouteManagerClass))
|
||||
|
||||
struct _NMRouteManager {
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
} NMRouteManagerClass;
|
||||
|
||||
GType nm_route_manager_get_type (void);
|
||||
|
||||
gboolean nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes);
|
||||
gboolean nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes);
|
||||
gboolean nm_route_manager_route_flush (NMRouteManager *self, int ifindex);
|
||||
|
||||
NMRouteManager *nm_route_manager_get (void);
|
||||
|
||||
#endif /* NM_ROUTE_MANAGER_H */
|
||||
|
|
@ -40,6 +40,7 @@ typedef struct _NMIP6Config NMIP6Config;
|
|||
typedef struct _NMManager NMManager;
|
||||
typedef struct _NMPolicy NMPolicy;
|
||||
typedef struct _NMRfkillManager NMRfkillManager;
|
||||
typedef struct _NMRouteManager NMRouteManager;
|
||||
typedef struct _NMSessionMonitor NMSessionMonitor;
|
||||
typedef struct _NMSleepMonitor NMSleepMonitor;
|
||||
|
||||
|
|
|
|||
|
|
@ -2340,207 +2340,6 @@ nm_platform_ip6_route_exists (NMPlatform *self, int ifindex, struct in6_addr net
|
|||
return klass->ip6_route_exists (self, ifindex, network, plen, metric);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
array_contains_ip4_route (const GArray *routes, const NMPlatformIP4Route *route)
|
||||
{
|
||||
guint len = routes ? routes->len : 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
NMPlatformIP4Route *c = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (route->network == c->network &&
|
||||
route->plen == c->plen &&
|
||||
route->gateway == c->gateway &&
|
||||
route->metric == c->metric)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
array_contains_ip6_route (const GArray *routes, const NMPlatformIP6Route *route)
|
||||
{
|
||||
guint len = routes ? routes->len : 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
NMPlatformIP6Route *c = &g_array_index (routes, NMPlatformIP6Route, i);
|
||||
|
||||
if (IN6_ARE_ADDR_EQUAL (&route->network, &c->network) &&
|
||||
route->plen == c->plen &&
|
||||
IN6_ARE_ADDR_EQUAL (&route->gateway, &c->gateway) &&
|
||||
route->metric == c->metric)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_ip4_route_sync:
|
||||
* @self: platform instance
|
||||
* @ifindex: Interface index
|
||||
* @known_routes: List of routes
|
||||
*
|
||||
* A convenience function to synchronize routes for a specific interface
|
||||
* with the least possible disturbance. It simply removes routes that are
|
||||
* not listed and adds routes that are.
|
||||
* Default routes are ignored (both in @known_routes and those already
|
||||
* configured on the device).
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_platform_ip4_route_sync (NMPlatform *self, int ifindex, const GArray *known_routes)
|
||||
{
|
||||
GArray *routes;
|
||||
NMPlatformIP4Route *route;
|
||||
const NMPlatformIP4Route *known_route;
|
||||
gboolean success;
|
||||
int i, i_type;
|
||||
|
||||
_CHECK_SELF (self, klass, FALSE);
|
||||
|
||||
/* Delete unknown routes */
|
||||
routes = nm_platform_ip4_route_get_all (self, ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT);
|
||||
for (i = 0; i < routes->len; i++) {
|
||||
route = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (!array_contains_ip4_route (known_routes, route))
|
||||
(void) nm_platform_ip4_route_delete (self, ifindex, route->network, route->plen, route->metric);
|
||||
}
|
||||
|
||||
if (!known_routes) {
|
||||
g_array_free (routes, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add missing routes */
|
||||
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
|
||||
for (i = 0; i < known_routes->len && success; i++) {
|
||||
known_route = &g_array_index (known_routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route))
|
||||
continue;
|
||||
|
||||
if ( (i_type == 0 && known_route->gateway != 0)
|
||||
|| (i_type == 1 && known_route->gateway == 0)) {
|
||||
/* Make two runs over the list of routes. On the first, only add
|
||||
* device routes, on the second the others (gateway routes). */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore routes that already exist */
|
||||
if (!array_contains_ip4_route (routes, known_route)) {
|
||||
success = nm_platform_ip4_route_add (self,
|
||||
ifindex,
|
||||
known_route->source,
|
||||
known_route->network,
|
||||
known_route->plen,
|
||||
known_route->gateway,
|
||||
0,
|
||||
known_route->metric,
|
||||
known_route->mss);
|
||||
if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) {
|
||||
nm_log_dbg (LOGD_PLATFORM, "ignore error adding IPv4 route to kernel: %s",
|
||||
nm_platform_ip4_route_to_string (known_route));
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (routes, TRUE);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_ip6_route_sync:
|
||||
* @self: platform instance
|
||||
* @ifindex: Interface index
|
||||
* @known_routes: List of routes
|
||||
*
|
||||
* A convenience function to synchronize routes for a specific interface
|
||||
* with the least possible disturbance. It simply removes routes that are
|
||||
* not listed and adds routes that are.
|
||||
* Default routes are ignored (both in @known_routes and those already
|
||||
* configured on the device).
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
nm_platform_ip6_route_sync (NMPlatform *self, int ifindex, const GArray *known_routes)
|
||||
{
|
||||
GArray *routes;
|
||||
NMPlatformIP6Route *route;
|
||||
const NMPlatformIP6Route *known_route;
|
||||
gboolean success;
|
||||
int i, i_type;
|
||||
|
||||
_CHECK_SELF (self, klass, FALSE);
|
||||
|
||||
/* Delete unknown routes */
|
||||
routes = nm_platform_ip6_route_get_all (self, ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT);
|
||||
for (i = 0; i < routes->len; i++) {
|
||||
route = &g_array_index (routes, NMPlatformIP6Route, i);
|
||||
route->ifindex = 0;
|
||||
|
||||
if (!array_contains_ip6_route (known_routes, route))
|
||||
nm_platform_ip6_route_delete (self, ifindex, route->network, route->plen, route->metric);
|
||||
}
|
||||
|
||||
if (!known_routes) {
|
||||
g_array_free (routes, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add missing routes */
|
||||
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
|
||||
for (i = 0; i < known_routes->len && success; i++) {
|
||||
known_route = &g_array_index (known_routes, NMPlatformIP6Route, i);
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route))
|
||||
continue;
|
||||
|
||||
if ( (i_type == 0 && !IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway))
|
||||
|| (i_type == 1 && IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway))) {
|
||||
/* Make two runs over the list of routes. On the first, only add
|
||||
* device routes, on the second the others (gateway routes). */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore routes that already exist */
|
||||
if (!array_contains_ip6_route (routes, known_route)) {
|
||||
success = nm_platform_ip6_route_add (self,
|
||||
ifindex,
|
||||
known_route->source,
|
||||
known_route->network,
|
||||
known_route->plen,
|
||||
known_route->gateway,
|
||||
known_route->metric,
|
||||
known_route->mss);
|
||||
if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) {
|
||||
nm_log_dbg (LOGD_PLATFORM, "ignore error adding IPv6 route to kernel: %s",
|
||||
nm_platform_ip6_route_to_string (known_route));
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (routes, TRUE);
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_route_flush (NMPlatform *self, int ifindex)
|
||||
{
|
||||
return nm_platform_ip4_route_sync (self, ifindex, NULL)
|
||||
&& nm_platform_ip6_route_sync (self, ifindex, NULL);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static const char *
|
||||
|
|
|
|||
|
|
@ -713,9 +713,6 @@ gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t
|
|||
gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric);
|
||||
gboolean nm_platform_ip4_route_exists (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric);
|
||||
gboolean nm_platform_ip6_route_exists (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric);
|
||||
gboolean nm_platform_ip4_route_sync (NMPlatform *self, int ifindex, const GArray *known_routes);
|
||||
gboolean nm_platform_ip6_route_sync (NMPlatform *self, int ifindex, const GArray *known_routes);
|
||||
gboolean nm_platform_route_flush (NMPlatform *self, int ifindex);
|
||||
|
||||
const char *nm_platform_link_to_string (const NMPlatformLink *link);
|
||||
const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "nm-agent-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "nm-route-manager.h"
|
||||
|
||||
#include "nm-vpn-connection-glue.h"
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ vpn_cleanup (NMVpnConnection *connection, NMDevice *parent_dev)
|
|||
|
||||
if (priv->ip_ifindex) {
|
||||
nm_platform_link_set_down (NM_PLATFORM_GET, priv->ip_ifindex);
|
||||
nm_platform_route_flush (NM_PLATFORM_GET, priv->ip_ifindex);
|
||||
nm_route_manager_route_flush (nm_route_manager_get (), priv->ip_ifindex);
|
||||
nm_platform_address_flush (NM_PLATFORM_GET, priv->ip_ifindex);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue