static void
netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer user_data)
{
	NMIP6Manager *manager = (NMIP6Manager *) user_data;
	NMIP6Device *device;
	struct nlmsghdr *hdr;

	hdr = nlmsg_hdr (msg);
	nm_log_dbg (LOGD_HW, "netlink event type %d", hdr->nlmsg_type);
	switch (hdr->nlmsg_type) {
	case RTM_NEWADDR:
	case RTM_DELADDR:
		device = process_address_change (manager, msg);
		break;
	case RTM_NEWROUTE:
	case RTM_DELROUTE:
		device = process_route_change (manager, msg);
		break;
	case RTM_NEWNDUSEROPT:
		device = process_nduseropt (manager, msg);
		break;
	case RTM_NEWLINK:
		device = process_newlink (manager, msg);
		break;
	default:
		return;
	}

	if (device) {
		nm_ip6_device_sync_from_netlink (device);
	}
}
void
nm_ip6_manager_begin_addrconf (NMIP6Manager *manager, int ifindex)
{
	NMIP6ManagerPrivate *priv;
	NMIP6Device *device;
	CallbackInfo *info;

	g_return_if_fail (NM_IS_IP6_MANAGER (manager));
	g_return_if_fail (ifindex > 0);

	priv = NM_IP6_MANAGER_GET_PRIVATE (manager);

	device = (NMIP6Device *) g_hash_table_lookup (priv->devices, GINT_TO_POINTER (ifindex));
	g_return_if_fail (device != NULL);

	nm_log_info (LOGD_IP6, "Activation (%s) Beginning IP6 addrconf.", device->iface);

	device->addrconf_complete = FALSE;
	device->ra_flags = 0;

	/* Set up a timeout on the transaction to kill it after the timeout */
	info = callback_info_new (device, FALSE);
	device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
	                                                         NM_IP6_TIMEOUT,
	                                                         finish_addrconf,
	                                                         info,
	                                                         (GDestroyNotify) g_free);

	/* Bounce IPv6 on the interface to ensure the kernel will start looking for
	 * new RAs; there doesn't seem to be a better way to do this right now.
	 */
	if (device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS) {
		nm_utils_do_sysctl (device->disable_ip6_path, "1");
		/* Wait until all existing IPv6 addresses have been removed from the link,
		 * to ensure they don't confuse our IPv6 addressing state machine.
		 */
		wait_for_no_addresses (manager, device);
		nm_utils_do_sysctl (device->disable_ip6_path, "0");
	}

	device->ip6flags_poll_id = g_timeout_add_seconds (1, poll_ip6_flags, priv->monitor);

	/* Kick off the initial IPv6 flags request */
	nm_netlink_monitor_request_ip6_info (priv->monitor, NULL);

	/* Sync flags, etc, from netlink; this will also notice if the
	 * device is already fully configured and schedule the
	 * ADDRCONF_COMPLETE signal in that case.
	 */
	nm_ip6_device_sync_from_netlink (device);
}
Ejemplo n.º 3
0
static void
netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer user_data)
{
	NMIP6Manager *manager = (NMIP6Manager *) user_data;
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	gboolean config_changed = FALSE;

	hdr = nlmsg_hdr (msg);
	nm_log_dbg (LOGD_HW, "netlink notificate type %d", hdr->nlmsg_type);
	switch (hdr->nlmsg_type) {
	case RTM_NEWADDR:
	case RTM_DELADDR:
		device = process_addr (manager, msg);
		config_changed = TRUE;
		break;
	case RTM_NEWROUTE:
	case RTM_DELROUTE:
		device = process_route (manager, msg);
		config_changed = TRUE;
		break;
	case RTM_NEWPREFIX:
		device = process_prefix (manager, msg);
		break;
	case RTM_NEWNDUSEROPT:
		device = process_nduseropt (manager, msg);
		config_changed = TRUE;
		break;
	case RTM_NEWLINK:
		device = process_newlink (manager, msg);
		config_changed = TRUE;
		break;
	default:
		return;
	}

	if (device) {
		nm_log_dbg (LOGD_IP6, "(%s): syncing device with netlink changes", device->iface);
		nm_ip6_device_sync_from_netlink (device, config_changed);
	}
}