ip6: save the accept_ra value and re-set it when the device is deactivated
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009 Red Hat, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <netinet/icmp6.h>
|
#include <netinet/icmp6.h>
|
||||||
|
|
||||||
#include <netlink/route/rtnl.h>
|
#include <netlink/route/rtnl.h>
|
||||||
@@ -68,6 +69,10 @@ typedef struct {
|
|||||||
char *iface;
|
char *iface;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
char *accept_ra_path;
|
||||||
|
gboolean accept_ra_save_valid;
|
||||||
|
guint32 accept_ra_save;
|
||||||
|
|
||||||
guint finish_addrconf_id;
|
guint finish_addrconf_id;
|
||||||
guint config_changed_id;
|
guint config_changed_id;
|
||||||
|
|
||||||
@@ -179,6 +184,14 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
|
|||||||
static void
|
static void
|
||||||
nm_ip6_device_destroy (NMIP6Device *device)
|
nm_ip6_device_destroy (NMIP6Device *device)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (device != NULL);
|
||||||
|
|
||||||
|
/* reset the saved RA value */
|
||||||
|
if (device->accept_ra_save_valid) {
|
||||||
|
nm_utils_do_sysctl (device->accept_ra_path,
|
||||||
|
device->accept_ra_save ? "1\n" : "0\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (device->finish_addrconf_id)
|
if (device->finish_addrconf_id)
|
||||||
g_source_remove (device->finish_addrconf_id);
|
g_source_remove (device->finish_addrconf_id);
|
||||||
if (device->config_changed_id)
|
if (device->config_changed_id)
|
||||||
@@ -189,6 +202,7 @@ nm_ip6_device_destroy (NMIP6Device *device)
|
|||||||
if (device->rdnss_timeout_id)
|
if (device->rdnss_timeout_id)
|
||||||
g_source_remove (device->rdnss_timeout_id);
|
g_source_remove (device->rdnss_timeout_id);
|
||||||
|
|
||||||
|
g_free (device->accept_ra_path);
|
||||||
g_slice_free (NMIP6Device, device);
|
g_slice_free (NMIP6Device, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,6 +614,8 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
|
|||||||
{
|
{
|
||||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||||
NMIP6Device *device;
|
NMIP6Device *device;
|
||||||
|
GError *error = NULL;
|
||||||
|
char *contents = NULL;
|
||||||
|
|
||||||
device = g_slice_new0 (NMIP6Device);
|
device = g_slice_new0 (NMIP6Device);
|
||||||
if (!device) {
|
if (!device) {
|
||||||
@@ -616,6 +632,14 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
|
|||||||
}
|
}
|
||||||
device->index = nm_netlink_iface_to_index (iface);
|
device->index = nm_netlink_iface_to_index (iface);
|
||||||
|
|
||||||
|
device->accept_ra_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", iface);
|
||||||
|
if (!device->accept_ra_path) {
|
||||||
|
nm_warning ("%s: Out of memory creating IP6 addrconf object "
|
||||||
|
"property 'accept_ra_path'.",
|
||||||
|
iface);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
device->manager = manager;
|
device->manager = manager;
|
||||||
|
|
||||||
device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));
|
device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));
|
||||||
@@ -623,6 +647,27 @@ nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
|
|||||||
g_hash_table_replace (priv->devices_by_iface, device->iface, device);
|
g_hash_table_replace (priv->devices_by_iface, device->iface, device);
|
||||||
g_hash_table_replace (priv->devices_by_index, GINT_TO_POINTER (device->index), device);
|
g_hash_table_replace (priv->devices_by_index, GINT_TO_POINTER (device->index), device);
|
||||||
|
|
||||||
|
/* Grab the original value of "accept_ra" so we can restore it when the
|
||||||
|
* device is taken down.
|
||||||
|
*/
|
||||||
|
if (!g_file_get_contents (device->accept_ra_path, &contents, NULL, &error)) {
|
||||||
|
nm_warning ("%s: error reading %s: (%d) %s",
|
||||||
|
iface, device->accept_ra_path,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
g_clear_error (&error);
|
||||||
|
} else {
|
||||||
|
long int tmp;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
tmp = strtol (contents, NULL, 10);
|
||||||
|
if ((errno == 0) && (tmp == 0 || tmp == 1)) {
|
||||||
|
device->accept_ra_save = (guint32) tmp;
|
||||||
|
device->accept_ra_save_valid = TRUE;
|
||||||
|
}
|
||||||
|
g_free (contents);
|
||||||
|
}
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -638,7 +683,6 @@ nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
|||||||
NMIP6ManagerPrivate *priv;
|
NMIP6ManagerPrivate *priv;
|
||||||
NMIP6Device *device;
|
NMIP6Device *device;
|
||||||
const char *method = NULL;
|
const char *method = NULL;
|
||||||
char *sysctl_path;
|
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
|
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
|
||||||
g_return_if_fail (iface != NULL);
|
g_return_if_fail (iface != NULL);
|
||||||
@@ -662,10 +706,9 @@ nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
|||||||
strcmp (iface, "all") != 0 &&
|
strcmp (iface, "all") != 0 &&
|
||||||
strcmp (iface, "default") != 0);
|
strcmp (iface, "default") != 0);
|
||||||
|
|
||||||
sysctl_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", iface);
|
/* Turn router advertisement acceptance on or off... */
|
||||||
nm_utils_do_sysctl (sysctl_path,
|
nm_utils_do_sysctl (device->accept_ra_path,
|
||||||
device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS ? "1\n" : "0\n");
|
device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS ? "1\n" : "0\n");
|
||||||
g_free (sysctl_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -607,21 +607,22 @@ nm_device_cleanup_ip6 (NMDevice *self)
|
|||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
if (priv->ip6_manager) {
|
if (!priv->ip6_manager)
|
||||||
if (priv->ip6_addrconf_sigid) {
|
return;
|
||||||
g_signal_handler_disconnect (priv->ip6_manager,
|
|
||||||
priv->ip6_addrconf_sigid);
|
|
||||||
priv->ip6_addrconf_sigid = 0;
|
|
||||||
}
|
|
||||||
if (priv->ip6_config_changed_sigid) {
|
|
||||||
g_signal_handler_disconnect (priv->ip6_manager,
|
|
||||||
priv->ip6_config_changed_sigid);
|
|
||||||
priv->ip6_config_changed_sigid = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (priv->ip6_manager);
|
if (priv->ip6_addrconf_sigid) {
|
||||||
priv->ip6_manager = NULL;
|
g_signal_handler_disconnect (priv->ip6_manager,
|
||||||
|
priv->ip6_addrconf_sigid);
|
||||||
|
priv->ip6_addrconf_sigid = 0;
|
||||||
}
|
}
|
||||||
|
if (priv->ip6_config_changed_sigid) {
|
||||||
|
g_signal_handler_disconnect (priv->ip6_manager,
|
||||||
|
priv->ip6_config_changed_sigid);
|
||||||
|
priv->ip6_config_changed_sigid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (priv->ip6_manager);
|
||||||
|
priv->ip6_manager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user