mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 17:00:29 +01:00
vpn: use nm-platform for default routes
This commit is contained in:
parent
91f8de7936
commit
96219b1d86
4 changed files with 93 additions and 52 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 72d437cf9349ccfb8723ea09b381b17c0a23ab88
|
||||
Subproject commit 8e11654015d91b62049315aa7f9a459d0ec2c82e
|
||||
|
|
@ -144,13 +144,13 @@ nm_system_device_set_ip4_route (int ifindex,
|
|||
return route;
|
||||
}
|
||||
|
||||
struct rtnl_route *
|
||||
NMPlatformIP4Route *
|
||||
nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
||||
{
|
||||
NMIP4Config *parent_config;
|
||||
guint32 parent_gw = 0, parent_prefix = 0, i;
|
||||
NMIP4Address *tmp;
|
||||
struct rtnl_route *route = NULL;
|
||||
NMPlatformIP4Route *route = g_new0 (NMPlatformIP4Route, 1);
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
|
||||
g_return_val_if_fail (vpn_gw != 0, NULL);
|
||||
|
|
@ -171,19 +171,37 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
|||
}
|
||||
}
|
||||
|
||||
if (!parent_gw)
|
||||
if (!parent_gw) {
|
||||
g_free (route);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
route->ifindex = nm_device_get_ip_ifindex (parent_device);
|
||||
route->network = vpn_gw;
|
||||
route->plen = 32;
|
||||
route->gateway = parent_gw;
|
||||
route->metric = 1024;
|
||||
route->mss = nm_ip4_config_get_mss (parent_config);
|
||||
|
||||
/* If the VPN gateway is in the same subnet as one of the parent device's
|
||||
* IP addresses, don't add the host route to it, but a route through the
|
||||
* parent device.
|
||||
*/
|
||||
if (ip4_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix)) {
|
||||
route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device),
|
||||
vpn_gw, 32, 0, 0, nm_ip4_config_get_mss (parent_config));
|
||||
} else {
|
||||
route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device),
|
||||
vpn_gw, 32, parent_gw, 0, nm_ip4_config_get_mss (parent_config));
|
||||
if (ip4_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix))
|
||||
route->gateway = 0;
|
||||
|
||||
if (!nm_platform_ip4_route_add (route->ifindex,
|
||||
route->network,
|
||||
route->plen,
|
||||
route->gateway,
|
||||
route->metric,
|
||||
route->mss)) {
|
||||
g_free (route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP4,
|
||||
"(%s): failed to add IPv4 route to VPN gateway: %s",
|
||||
nm_device_get_iface (parent_device),
|
||||
nm_platform_get_error_msg ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return route;
|
||||
|
|
@ -354,16 +372,16 @@ ip6_dest_in_same_subnet (NMIP6Config *config, const struct in6_addr *dest, guint
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
struct rtnl_route *
|
||||
NMPlatformIP6Route *
|
||||
nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||
const struct in6_addr *vpn_gw)
|
||||
{
|
||||
NMIP6Config *parent_config;
|
||||
const struct in6_addr *parent_gw = NULL;
|
||||
guint32 parent_prefix = 0;
|
||||
int i, err;
|
||||
int i;
|
||||
NMIP6Address *tmp;
|
||||
struct rtnl_route *route = NULL;
|
||||
NMPlatformIP6Route *route = g_new0 (NMPlatformIP6Route, 1);
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
|
||||
g_return_val_if_fail (vpn_gw != NULL, NULL);
|
||||
|
|
@ -385,28 +403,39 @@ nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
|||
}
|
||||
}
|
||||
|
||||
if (!parent_gw)
|
||||
if (!parent_gw) {
|
||||
g_free (route);
|
||||
return NULL;
|
||||
|
||||
if (ip6_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix)) {
|
||||
err = nm_system_set_ip6_route (nm_device_get_ip_ifindex (parent_device),
|
||||
vpn_gw, 128, NULL, 0,
|
||||
nm_ip6_config_get_mss (parent_config),
|
||||
RTPROT_UNSPEC, RT_TABLE_UNSPEC,
|
||||
&route);
|
||||
} else {
|
||||
err = nm_system_set_ip6_route (nm_device_get_ip_ifindex (parent_device),
|
||||
vpn_gw, 128, parent_gw, 0,
|
||||
nm_ip6_config_get_mss (parent_config),
|
||||
RTPROT_UNSPEC, RT_TABLE_UNSPEC,
|
||||
&route);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
route->ifindex = nm_device_get_ip_ifindex (parent_device);
|
||||
route->network = *vpn_gw;
|
||||
route->plen = 128;
|
||||
route->gateway = *parent_gw;
|
||||
route->metric = 1024;
|
||||
route->mss = nm_ip6_config_get_mss (parent_config);
|
||||
|
||||
/* If the VPN gateway is in the same subnet as one of the parent device's
|
||||
* IP addresses, don't add the host route to it, but a route through the
|
||||
* parent device.
|
||||
*/
|
||||
if (ip6_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix))
|
||||
route->gateway = in6addr_any;
|
||||
|
||||
if (!nm_platform_ip6_route_add (route->ifindex,
|
||||
route->network,
|
||||
route->plen,
|
||||
route->gateway,
|
||||
route->metric,
|
||||
route->mss)) {
|
||||
g_free (route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to add IPv6 route to VPN gateway (%d)",
|
||||
nm_device_get_iface (parent_device), err);
|
||||
"(%s): failed to add IPv6 route to VPN gateway: %s",
|
||||
nm_device_get_iface (parent_device),
|
||||
nm_platform_get_error_msg ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <glib.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#include "nm-platform.h"
|
||||
#include "nm-device.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-setting-bond.h"
|
||||
|
|
@ -52,9 +53,9 @@ gboolean nm_system_replace_default_ip6_route_vpn (int ifindex,
|
|||
int parent_ifindex,
|
||||
guint32 parent_mss);
|
||||
|
||||
struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device,
|
||||
NMPlatformIP4Route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device,
|
||||
guint32 vpn_gw);
|
||||
struct rtnl_route *nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||
NMPlatformIP6Route *nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||
const struct in6_addr *vpn_gw);
|
||||
|
||||
gboolean nm_system_iface_flush_addresses (int ifindex, int family);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include "nm-active-connection.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-netlink-utils.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
#include "nm-dispatcher.h"
|
||||
|
|
@ -92,7 +91,8 @@ typedef struct {
|
|||
char *banner;
|
||||
guint32 mtu;
|
||||
|
||||
struct rtnl_route *gw_route;
|
||||
NMPlatformIP4Route *ip4_gw_route;
|
||||
NMPlatformIP6Route *ip6_gw_route;
|
||||
} NMVPNConnectionPrivate;
|
||||
|
||||
#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
|
||||
|
|
@ -168,10 +168,22 @@ vpn_cleanup (NMVPNConnection *connection)
|
|||
nm_platform_address_flush (priv->ip_ifindex);
|
||||
}
|
||||
|
||||
if (priv->gw_route) {
|
||||
nm_netlink_route_delete (priv->gw_route);
|
||||
rtnl_route_put (priv->gw_route);
|
||||
priv->gw_route = NULL;
|
||||
if (priv->ip4_gw_route) {
|
||||
nm_platform_ip4_route_delete (
|
||||
priv->ip4_gw_route->ifindex,
|
||||
priv->ip4_gw_route->network,
|
||||
priv->ip4_gw_route->plen,
|
||||
priv->ip4_gw_route->metric);
|
||||
g_clear_pointer (&priv->ip4_gw_route, g_free);
|
||||
}
|
||||
|
||||
if (priv->ip6_gw_route) {
|
||||
nm_platform_ip6_route_delete (
|
||||
priv->ip6_gw_route->ifindex,
|
||||
priv->ip6_gw_route->network,
|
||||
priv->ip6_gw_route->plen,
|
||||
priv->ip6_gw_route->metric);
|
||||
g_clear_pointer (&priv->ip6_gw_route, g_free);
|
||||
}
|
||||
|
||||
g_free (priv->banner);
|
||||
|
|
@ -309,9 +321,8 @@ device_ip4_config_changed (NMDevice *device,
|
|||
|
||||
/* Re-add the VPN gateway route */
|
||||
if (priv->ip4_external_gw) {
|
||||
if (priv->gw_route)
|
||||
rtnl_route_put (priv->gw_route);
|
||||
priv->gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev,
|
||||
g_free (&priv->ip4_gw_route);
|
||||
priv->ip4_gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip4_external_gw);
|
||||
}
|
||||
}
|
||||
|
|
@ -330,10 +341,9 @@ device_ip6_config_changed (NMDevice *device,
|
|||
|
||||
/* Re-add the VPN gateway route */
|
||||
if (priv->ip6_external_gw) {
|
||||
if (priv->gw_route)
|
||||
rtnl_route_put (priv->gw_route);
|
||||
priv->gw_route = nm_system_add_ip6_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip6_external_gw);
|
||||
g_free (priv->ip6_gw_route);
|
||||
priv->ip6_gw_route = nm_system_add_ip6_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip6_external_gw);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -612,14 +622,14 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
|
|||
}
|
||||
|
||||
/* Add any explicit route to the VPN gateway through the parent device */
|
||||
g_clear_pointer (&priv->ip4_gw_route, g_free);
|
||||
g_clear_pointer (&priv->ip6_gw_route, g_free);
|
||||
if (priv->ip4_external_gw) {
|
||||
priv->gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip4_gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip4_external_gw);
|
||||
} else if (priv->ip6_external_gw) {
|
||||
priv->gw_route = nm_system_add_ip6_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip6_gw_route = nm_system_add_ip6_vpn_gateway_route (priv->parent_dev,
|
||||
priv->ip6_external_gw);
|
||||
} else {
|
||||
priv->gw_route = NULL;
|
||||
}
|
||||
|
||||
nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) complete.",
|
||||
|
|
@ -689,7 +699,7 @@ process_generic_config (NMVPNConnection *connection,
|
|||
|
||||
/* Grab the interface index for address/routing operations */
|
||||
priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface);
|
||||
if (priv->ip_ifindex < 0) {
|
||||
if (!priv->ip_ifindex) {
|
||||
nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface);
|
||||
nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
||||
return FALSE;
|
||||
|
|
@ -1500,8 +1510,9 @@ dispose (GObject *object)
|
|||
}
|
||||
priv->disposed = TRUE;
|
||||
|
||||
if (priv->gw_route)
|
||||
rtnl_route_put (priv->gw_route);
|
||||
g_clear_pointer (&priv->ip4_gw_route, g_free);
|
||||
g_clear_pointer (&priv->ip6_gw_route, g_free);
|
||||
|
||||
if (priv->ip6_internal_gw)
|
||||
g_free (priv->ip6_internal_gw);
|
||||
if (priv->ip6_external_gw)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue