ip6: save the accept_ra value and re-set it when the device is deactivated

This commit is contained in:
Dan Williams
2009-10-19 15:38:21 -07:00
parent 442dc676ef
commit 23fec8dc72
2 changed files with 62 additions and 18 deletions

View File

@@ -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

View File

@@ -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;
} }
/* /*