mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-03 20:40:34 +01:00
2008-11-07 Dan Williams <dcbw@redhat.com>
Fix deletion of VPN gateway route on DHCP renew (bgo #558133) * src/NetworkManagerSystem.c src/NetworkManagerSystem.h - (nm_system_device_set_ip4_route): return the route that was added - (nm_system_add_ip4_vpn_gateway_route): make add_vpn_gateway_route() public, clean up, and return the route that was added - (nm_system_apply_ip4_config): remove VPN related stuff to simplify, since nm_system_add_ip4_vpn_gateway_route() is now available; add flags to allow only certain attributes of the NMIP4Config to be applied * src/nm-device.c - (handle_dhcp_lease_change): don't touch the DHCP4 config on failure - (nm_device_set_ip4_config): use nm_ip4_config_diff() to only apply what's really changed between the old and new configs; don't export the new IP4 config on failure; always send the DNS info to the named manager * src/vpn-manager/nm-vpn-connection.c - (device_ip4_config_changed, nm_vpn_connection_new, dispose): track the parent device's IP4Config and re-add the VPN gateway route when it changes - (nm_vpn_connection_ip4_config_get): add the VPN gateway route (since nm_system_apply_ip4_config() no longer does) and cache it for later - (connection_state_changed): move cleanup code to its own function - (vpn_cleanup): delete any previously added VPN gateway route; and re-apply the parent device's addresses and routes using nm_system_apply_ip4_config(), not nm_device_set_ip4_config() git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4277 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
5fdb74935c
commit
214114fb2d
6 changed files with 231 additions and 121 deletions
32
ChangeLog
32
ChangeLog
|
|
@ -1,3 +1,35 @@
|
|||
2008-11-07 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
Fix deletion of VPN gateway route on DHCP renew (bgo #558133)
|
||||
|
||||
* src/NetworkManagerSystem.c
|
||||
src/NetworkManagerSystem.h
|
||||
- (nm_system_device_set_ip4_route): return the route that was added
|
||||
- (nm_system_add_ip4_vpn_gateway_route): make add_vpn_gateway_route()
|
||||
public, clean up, and return the route that was added
|
||||
- (nm_system_apply_ip4_config): remove VPN related stuff to simplify,
|
||||
since nm_system_add_ip4_vpn_gateway_route() is now available; add
|
||||
flags to allow only certain attributes of the NMIP4Config to be
|
||||
applied
|
||||
|
||||
* src/nm-device.c
|
||||
- (handle_dhcp_lease_change): don't touch the DHCP4 config on failure
|
||||
- (nm_device_set_ip4_config): use nm_ip4_config_diff() to only apply
|
||||
what's really changed between the old and new configs; don't export
|
||||
the new IP4 config on failure; always send the DNS info to the
|
||||
named manager
|
||||
|
||||
* src/vpn-manager/nm-vpn-connection.c
|
||||
- (device_ip4_config_changed, nm_vpn_connection_new, dispose): track the
|
||||
parent device's IP4Config and re-add the VPN gateway route when it
|
||||
changes
|
||||
- (nm_vpn_connection_ip4_config_get): add the VPN gateway route (since
|
||||
nm_system_apply_ip4_config() no longer does) and cache it for later
|
||||
- (connection_state_changed): move cleanup code to its own function
|
||||
- (vpn_cleanup): delete any previously added VPN gateway route; and
|
||||
re-apply the parent device's addresses and routes using
|
||||
nm_system_apply_ip4_config(), not nm_device_set_ip4_config()
|
||||
|
||||
2008-11-07 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* src/nm-ip4-config.c
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ create_route (int iface_idx, int mss)
|
|||
return route;
|
||||
}
|
||||
|
||||
static void
|
||||
static struct rtnl_route *
|
||||
nm_system_device_set_ip4_route (const char *iface,
|
||||
guint32 ip4_dest,
|
||||
guint32 ip4_prefix,
|
||||
|
|
@ -118,17 +118,17 @@ nm_system_device_set_ip4_route (const char *iface,
|
|||
int err, iface_idx;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_if_fail (nlh != NULL);
|
||||
g_return_val_if_fail (nlh != NULL, NULL);
|
||||
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
g_return_if_fail (iface_idx >= 0);
|
||||
g_return_val_if_fail (iface_idx >= 0, NULL);
|
||||
|
||||
route = create_route (iface_idx, mss);
|
||||
g_return_if_fail (route != NULL);
|
||||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
/* Destination */
|
||||
dest_addr = nl_addr_build (AF_INET, &ip4_dest, sizeof (ip4_dest));
|
||||
g_return_if_fail (dest_addr != NULL);
|
||||
g_return_val_if_fail (dest_addr != NULL, NULL);
|
||||
nl_addr_set_prefixlen (dest_addr, (int) ip4_prefix);
|
||||
|
||||
rtnl_route_set_dst (route, dest_addr);
|
||||
|
|
@ -143,7 +143,7 @@ nm_system_device_set_ip4_route (const char *iface,
|
|||
} else {
|
||||
nm_warning ("Invalid gateway");
|
||||
rtnl_route_put (route);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,17 +168,20 @@ nm_system_device_set_ip4_route (const char *iface,
|
|||
if (err)
|
||||
rtnl_route_del (nlh, route2, 0);
|
||||
}
|
||||
|
||||
rtnl_route_put (route2);
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
nm_warning ("Failed to set IPv4 route on '%s': %s", iface, nl_geterror ());
|
||||
|
||||
rtnl_route_put (route);
|
||||
if (gw_addr)
|
||||
nl_addr_put (gw_addr);
|
||||
|
||||
if (err) {
|
||||
nm_warning ("Failed to set IPv4 route on '%s': %s", iface, nl_geterror ());
|
||||
rtnl_route_put (route);
|
||||
route = NULL;
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -267,23 +270,22 @@ add_ip4_addresses (NMIP4Config *config, const char *iface)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_vpn_gateway_route (NMDevice *parent_device,
|
||||
const char *iface,
|
||||
NMIP4Config *vpn_config)
|
||||
struct rtnl_route *
|
||||
nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config)
|
||||
{
|
||||
NMIP4Config *parent_config;
|
||||
guint32 parent_gw = 0, parent_prefix = 0, vpn_gw = 0, i;
|
||||
NMIP4Address *tmp;
|
||||
struct rtnl_route *route = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (parent_device));
|
||||
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
|
||||
|
||||
/* Set up a route to the VPN gateway's public IP address through the default
|
||||
* network device if the VPN gateway is on a different subnet.
|
||||
*/
|
||||
|
||||
parent_config = nm_device_get_ip4_config (parent_device);
|
||||
g_return_if_fail (parent_config != NULL);
|
||||
g_return_val_if_fail (parent_config != NULL, NULL);
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_addresses (parent_config); i++) {
|
||||
tmp = nm_ip4_config_get_address (parent_config, i);
|
||||
|
|
@ -303,19 +305,21 @@ add_vpn_gateway_route (NMDevice *parent_device,
|
|||
}
|
||||
|
||||
if (!parent_gw || !vpn_gw)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* 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)) {
|
||||
nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
|
||||
vpn_gw, 32, 0, 0, nm_ip4_config_get_mss (parent_config));
|
||||
route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
|
||||
vpn_gw, 32, 0, 0, nm_ip4_config_get_mss (parent_config));
|
||||
} else {
|
||||
nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
|
||||
vpn_gw, 32, parent_gw, 0, nm_ip4_config_get_mss (parent_config));
|
||||
route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
|
||||
vpn_gw, 32, parent_gw, 0, nm_ip4_config_get_mss (parent_config));
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -325,46 +329,49 @@ add_vpn_gateway_route (NMDevice *parent_device,
|
|||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_apply_ip4_config (NMDevice *device,
|
||||
const char *iface,
|
||||
nm_system_apply_ip4_config (const char *iface,
|
||||
NMIP4Config *config,
|
||||
int priority,
|
||||
gboolean is_vpn)
|
||||
NMIP4ConfigCompareFlags flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
if (!add_ip4_addresses (config, iface))
|
||||
return FALSE;
|
||||
|
||||
if (is_vpn)
|
||||
add_vpn_gateway_route (device, iface, config);
|
||||
|
||||
sleep (1);
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
|
||||
NMIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
|
||||
/* Don't add the route if it's more specific than one of the subnets
|
||||
* the device already has an IP address on.
|
||||
*/
|
||||
if (ip4_dest_in_same_subnet (config,
|
||||
nm_ip4_route_get_dest (route),
|
||||
nm_ip4_route_get_prefix (route)))
|
||||
continue;
|
||||
|
||||
nm_system_device_set_ip4_route (iface,
|
||||
nm_ip4_route_get_dest (route),
|
||||
nm_ip4_route_get_prefix (route),
|
||||
nm_ip4_route_get_next_hop (route),
|
||||
nm_ip4_route_get_metric (route),
|
||||
nm_ip4_config_get_mss (config));
|
||||
if (flags & NM_IP4_COMPARE_FLAG_ADDRESSES) {
|
||||
if (!add_ip4_addresses (config, iface))
|
||||
return FALSE;
|
||||
sleep (1);
|
||||
}
|
||||
|
||||
if (nm_ip4_config_get_mtu (config))
|
||||
nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
|
||||
if (flags & NM_IP4_COMPARE_FLAG_ROUTES) {
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
|
||||
NMIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
struct rtnl_route *tmp;
|
||||
|
||||
/* Don't add the route if it's more specific than one of the subnets
|
||||
* the device already has an IP address on.
|
||||
*/
|
||||
if (ip4_dest_in_same_subnet (config,
|
||||
nm_ip4_route_get_dest (route),
|
||||
nm_ip4_route_get_prefix (route)))
|
||||
continue;
|
||||
|
||||
tmp = nm_system_device_set_ip4_route (iface,
|
||||
nm_ip4_route_get_dest (route),
|
||||
nm_ip4_route_get_prefix (route),
|
||||
nm_ip4_route_get_next_hop (route),
|
||||
nm_ip4_route_get_metric (route),
|
||||
nm_ip4_config_get_mss (config));
|
||||
rtnl_route_put (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & NM_IP4_COMPARE_FLAG_MTU) {
|
||||
if (nm_ip4_config_get_mtu (config))
|
||||
nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
|
||||
}
|
||||
|
||||
if (priority > 0)
|
||||
nm_system_device_set_priority (iface, config, priority);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
#ifndef NETWORK_MANAGER_SYSTEM_H
|
||||
#define NETWORK_MANAGER_SYSTEM_H
|
||||
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "nm-device.h"
|
||||
#include "nm-ip4-config.h"
|
||||
|
|
@ -44,17 +47,19 @@ gboolean nm_system_replace_default_ip4_route_vpn (const char *iface,
|
|||
const char *parent_iface,
|
||||
guint32 parent_mss);
|
||||
|
||||
struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config);
|
||||
|
||||
|
||||
void nm_system_device_flush_ip4_addresses (NMDevice *dev);
|
||||
void nm_system_device_flush_ip4_addresses_with_iface (const char *iface);
|
||||
|
||||
void nm_system_enable_loopback (void);
|
||||
void nm_system_update_dns (void);
|
||||
|
||||
gboolean nm_system_apply_ip4_config (NMDevice *device,
|
||||
const char *iface,
|
||||
gboolean nm_system_apply_ip4_config (const char *iface,
|
||||
NMIP4Config *config,
|
||||
int priority,
|
||||
gboolean is_vpn);
|
||||
NMIP4ConfigCompareFlags flags);
|
||||
|
||||
gboolean nm_system_device_set_up_down (NMDevice *dev,
|
||||
gboolean up,
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReas
|
|||
static gboolean nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware);
|
||||
static gboolean nm_device_is_up (NMDevice *self);
|
||||
|
||||
static gboolean nm_device_set_ip4_config (NMDevice *dev, NMIP4Config *config, NMDeviceStateReason *reason);
|
||||
|
||||
static void
|
||||
device_interface_init (NMDeviceInterface *device_interface_class)
|
||||
{
|
||||
|
|
@ -1754,12 +1756,12 @@ handle_dhcp_lease_change (NMDevice *device)
|
|||
|
||||
g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config);
|
||||
|
||||
if (!nm_device_set_ip4_config (device, config, &reason)) {
|
||||
if (nm_device_set_ip4_config (device, config, &reason))
|
||||
nm_dhcp_manager_set_dhcp4_config (priv->dhcp_manager, ip_iface, priv->dhcp4_config);
|
||||
else {
|
||||
nm_warning ("Failed to update IP4 config in response to DHCP event.");
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||
}
|
||||
|
||||
nm_dhcp_manager_set_dhcp4_config (priv->dhcp_manager, ip_iface, priv->dhcp4_config);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1905,12 +1907,17 @@ nm_device_get_ip4_config (NMDevice *self)
|
|||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReason *reason)
|
||||
static gboolean
|
||||
nm_device_set_ip4_config (NMDevice *self,
|
||||
NMIP4Config *new_config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
const char *ip_iface;
|
||||
gboolean success;
|
||||
NMIP4Config *old_config = NULL;
|
||||
gboolean success = TRUE;
|
||||
NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL;
|
||||
NMNamedManager *named_mgr;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||
g_return_val_if_fail (reason != NULL, FALSE);
|
||||
|
|
@ -1918,30 +1925,39 @@ nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReas
|
|||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
ip_iface = nm_device_get_ip_iface (self);
|
||||
|
||||
if (priv->ip4_config) {
|
||||
NMNamedManager *named_mgr;
|
||||
old_config = priv->ip4_config;
|
||||
|
||||
if (new_config && old_config)
|
||||
diff = nm_ip4_config_diff (new_config, old_config);
|
||||
|
||||
/* No actual change, do nothing */
|
||||
if (diff == NM_IP4_COMPARE_FLAG_NONE)
|
||||
return TRUE;
|
||||
|
||||
named_mgr = nm_named_manager_get ();
|
||||
if (old_config) {
|
||||
/* Remove any previous IP4 Config from the named manager */
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_remove_ip4_config (named_mgr, ip_iface, priv->ip4_config);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
g_object_unref (priv->ip4_config);
|
||||
nm_named_manager_remove_ip4_config (named_mgr, ip_iface, old_config);
|
||||
g_object_unref (old_config);
|
||||
priv->ip4_config = NULL;
|
||||
}
|
||||
|
||||
if (!config)
|
||||
return TRUE;
|
||||
if (new_config) {
|
||||
priv->ip4_config = g_object_ref (new_config);
|
||||
|
||||
priv->ip4_config = g_object_ref (config);
|
||||
success = nm_system_apply_ip4_config (ip_iface, new_config, nm_device_get_priority (self), diff);
|
||||
if (success) {
|
||||
/* Export over D-Bus */
|
||||
if (!nm_ip4_config_get_dbus_path (new_config))
|
||||
nm_ip4_config_export (new_config);
|
||||
|
||||
/* Export over D-Bus if needed */
|
||||
if (!nm_ip4_config_get_dbus_path (config))
|
||||
nm_ip4_config_export (config);
|
||||
/* Add the DNS information to the named manager */
|
||||
nm_named_manager_add_ip4_config (named_mgr, ip_iface, new_config, NM_NAMED_IP_CONFIG_TYPE_DEFAULT);
|
||||
|
||||
success = nm_system_apply_ip4_config (self, ip_iface, config, nm_device_get_priority (self), FALSE);
|
||||
if (success)
|
||||
nm_device_update_ip4_address (self);
|
||||
nm_device_update_ip4_address (self);
|
||||
}
|
||||
}
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_IP4_CONFIG);
|
||||
|
||||
|
|
|
|||
|
|
@ -139,9 +139,6 @@ void nm_device_set_use_dhcp (NMDevice *dev,
|
|||
NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *dev);
|
||||
|
||||
NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
|
||||
gboolean nm_device_set_ip4_config (NMDevice *dev,
|
||||
NMIP4Config *config,
|
||||
NMDeviceStateReason *reason);
|
||||
|
||||
void * nm_device_get_system_config_data (NMDevice *dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-named-manager.h"
|
||||
#include "nm-netlink.h"
|
||||
|
||||
#include "nm-vpn-connection-glue.h"
|
||||
|
||||
|
|
@ -56,22 +57,25 @@ typedef struct {
|
|||
DBusGProxyCall *secrets_call;
|
||||
|
||||
NMActRequest *act_request;
|
||||
NMDevice *parent_dev;
|
||||
char *ac_path;
|
||||
|
||||
NMDevice *parent_dev;
|
||||
gulong device_monitor;
|
||||
gulong device_ip4;
|
||||
|
||||
gboolean is_default;
|
||||
NMActiveConnectionState state;
|
||||
|
||||
NMVPNConnectionState vpn_state;
|
||||
NMVPNConnectionStateReason failure_reason;
|
||||
gulong device_monitor;
|
||||
DBusGProxy *proxy;
|
||||
guint ipconfig_timeout;
|
||||
NMIP4Config *ip4_config;
|
||||
guint32 ip4_internal_gw;
|
||||
char *tundev;
|
||||
char *tapdev;
|
||||
char *banner;
|
||||
|
||||
struct rtnl_route *gw_route;
|
||||
} NMVPNConnectionPrivate;
|
||||
|
||||
#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
|
||||
|
|
@ -155,7 +159,7 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
|
|||
nm_utils_call_dispatcher ("vpn-up",
|
||||
priv->connection,
|
||||
priv->parent_dev,
|
||||
priv->tapdev ? priv->tapdev : priv->tundev);
|
||||
priv->tundev);
|
||||
break;
|
||||
case NM_VPN_CONNECTION_STATE_FAILED:
|
||||
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
|
||||
|
|
@ -163,7 +167,7 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
|
|||
nm_utils_call_dispatcher ("vpn-down",
|
||||
priv->connection,
|
||||
priv->parent_dev,
|
||||
priv->tapdev ? priv->tapdev : priv->tundev);
|
||||
priv->tundev);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -193,6 +197,24 @@ device_state_changed (NMDevice *device,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
device_ip4_config_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVPNConnection *vpn = NM_VPN_CONNECTION (user_data);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
|
||||
|
||||
if (priv->vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
|
||||
return;
|
||||
|
||||
if (priv->gw_route)
|
||||
rtnl_route_put (priv->gw_route);
|
||||
|
||||
/* Re-add the VPN gateway route */
|
||||
priv->gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev, priv->ip4_config);
|
||||
}
|
||||
|
||||
NMVPNConnection *
|
||||
nm_vpn_connection_new (NMConnection *connection,
|
||||
NMActRequest *act_request,
|
||||
|
|
@ -218,6 +240,10 @@ nm_vpn_connection_new (NMConnection *connection,
|
|||
priv->device_monitor = g_signal_connect (parent_device, "state-changed",
|
||||
G_CALLBACK (device_state_changed),
|
||||
vpn_connection);
|
||||
|
||||
priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
|
||||
G_CALLBACK (device_ip4_config_changed),
|
||||
vpn_connection);
|
||||
return vpn_connection;
|
||||
}
|
||||
|
||||
|
|
@ -470,9 +496,12 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
|
|||
|
||||
nm_system_device_set_up_down_with_iface (priv->tundev, TRUE, NULL);
|
||||
|
||||
if (nm_system_apply_ip4_config (priv->parent_dev, priv->tundev, config, 0, TRUE)) {
|
||||
if (nm_system_apply_ip4_config (priv->tundev, config, 0, NM_IP4_COMPARE_FLAG_ALL)) {
|
||||
NMNamedManager *named_mgr;
|
||||
|
||||
/* Add any explicit route to the VPN gateway through the parent device */
|
||||
priv->gw_route = nm_system_add_ip4_vpn_gateway_route (priv->parent_dev, config);
|
||||
|
||||
/* Add the VPN to DNS */
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_add_ip4_config (named_mgr, priv->tundev, config, NM_NAMED_IP_CONFIG_TYPE_VPN);
|
||||
|
|
@ -889,6 +918,58 @@ call_need_secrets (NMVPNConnection *vpn_connection)
|
|||
g_hash_table_destroy (settings);
|
||||
}
|
||||
|
||||
static void
|
||||
vpn_cleanup (NMVPNConnection *connection)
|
||||
{
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
if (priv->tundev) {
|
||||
nm_system_device_set_up_down_with_iface (priv->tundev, FALSE, NULL);
|
||||
nm_system_device_flush_ip4_routes_with_iface (priv->tundev);
|
||||
nm_system_device_flush_ip4_addresses_with_iface (priv->tundev);
|
||||
}
|
||||
|
||||
if (priv->ip4_config) {
|
||||
NMIP4Config *parent_config;
|
||||
NMNamedManager *named_mgr;
|
||||
|
||||
/* Remove attributes of the VPN's IP4 Config */
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_remove_ip4_config (named_mgr, priv->tundev, priv->ip4_config);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
/* Remove any previously added VPN gateway host route */
|
||||
if (priv->gw_route)
|
||||
rtnl_route_del (nm_netlink_get_default_handle (), priv->gw_route, 0);
|
||||
|
||||
/* Reset routes and addresses of the currently active device */
|
||||
parent_config = nm_device_get_ip4_config (priv->parent_dev);
|
||||
if (parent_config) {
|
||||
if (!nm_system_apply_ip4_config (nm_device_get_ip_iface (priv->parent_dev),
|
||||
nm_device_get_ip4_config (priv->parent_dev),
|
||||
nm_device_get_priority (priv->parent_dev),
|
||||
NM_IP4_COMPARE_FLAG_ADDRESSES | NM_IP4_COMPARE_FLAG_ROUTES)) {
|
||||
nm_warning ("%s: failed to re-apply VPN parent device addresses and routes.", __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->gw_route) {
|
||||
rtnl_route_put (priv->gw_route);
|
||||
priv->gw_route = NULL;
|
||||
}
|
||||
|
||||
if (priv->banner) {
|
||||
g_free (priv->banner);
|
||||
priv->banner = NULL;
|
||||
}
|
||||
|
||||
if (priv->tundev) {
|
||||
g_free (priv->tundev);
|
||||
priv->tundev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connection_state_changed (NMVPNConnection *connection,
|
||||
NMVPNConnectionState state,
|
||||
|
|
@ -916,41 +997,7 @@ connection_state_changed (NMVPNConnection *connection,
|
|||
g_object_unref (priv->proxy);
|
||||
priv->proxy = NULL;
|
||||
}
|
||||
|
||||
if (priv->tundev) {
|
||||
nm_system_device_set_up_down_with_iface (priv->tundev, FALSE, NULL);
|
||||
nm_system_device_flush_ip4_routes_with_iface (priv->tundev);
|
||||
nm_system_device_flush_ip4_addresses_with_iface (priv->tundev);
|
||||
}
|
||||
|
||||
if (priv->ip4_config) {
|
||||
NMIP4Config *dev_ip4_config;
|
||||
NMNamedManager *named_mgr;
|
||||
|
||||
/* Remove attributes of the VPN's IP4 Config */
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_remove_ip4_config (named_mgr, priv->tundev, priv->ip4_config);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
/* Reset routes, nameservers, and domains of the currently active device */
|
||||
dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev);
|
||||
if (dev_ip4_config) {
|
||||
NMDeviceStateReason dev_reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
|
||||
/* Since the config we're setting is also the device's current
|
||||
* config, have to ref the config to ensure it doesn't get
|
||||
* destroyed when the device unrefs it in nm_device_set_ip4_config().
|
||||
*/
|
||||
nm_device_set_ip4_config (priv->parent_dev,
|
||||
g_object_ref (dev_ip4_config),
|
||||
&dev_reason);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->banner) {
|
||||
g_free (priv->banner);
|
||||
priv->banner = NULL;
|
||||
}
|
||||
vpn_cleanup (connection);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -987,7 +1034,13 @@ dispose (GObject *object)
|
|||
|
||||
cleanup_secrets_dbus_call (NM_VPN_CONNECTION (object));
|
||||
|
||||
if (priv->gw_route)
|
||||
rtnl_route_put (priv->gw_route);
|
||||
|
||||
if (priv->parent_dev) {
|
||||
if (priv->device_ip4)
|
||||
g_signal_handler_disconnect (priv->parent_dev, priv->device_ip4);
|
||||
|
||||
if (priv->device_monitor)
|
||||
g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue