Blame src/nm-dispatcher.c

Packit Service b23acc
// SPDX-License-Identifier: GPL-2.0+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2004 - 2018 Red Hat, Inc.
Packit Service b23acc
 * Copyright (C) 2005 - 2008 Novell, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#include "nm-default.h"
Packit Service b23acc
Packit Service b23acc
#include "nm-dispatcher.h"
Packit Service b23acc
Packit Service b23acc
#include "nm-libnm-core-aux/nm-dispatcher-api.h"
Packit Service b23acc
#include "NetworkManagerUtils.h"
Packit Service b23acc
#include "nm-utils.h"
Packit Service b23acc
#include "nm-connectivity.h"
Packit Service b23acc
#include "nm-act-request.h"
Packit Service b23acc
#include "devices/nm-device.h"
Packit Service b23acc
#include "nm-dhcp-config.h"
Packit Service b23acc
#include "nm-proxy-config.h"
Packit Service b23acc
#include "nm-ip4-config.h"
Packit Service b23acc
#include "nm-ip6-config.h"
Packit Service b23acc
#include "nm-manager.h"
Packit Service b23acc
#include "settings/nm-settings-connection.h"
Packit Service b23acc
#include "platform/nm-platform.h"
Packit Service b23acc
#include "nm-core-internal.h"
Packit Service b23acc
Packit Service b23acc
#define CALL_TIMEOUT (1000 * 60 * 10)  /* 10 minutes for all scripts */
Packit Service b23acc
Packit Service b23acc
#define _NMLOG_DOMAIN      LOGD_DISPATCH
Packit Service b23acc
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "dispatcher", __VA_ARGS__)
Packit Service b23acc
Packit Service b23acc
#define _NMLOG2_DOMAIN     LOGD_DISPATCH
Packit Service b23acc
#define _NMLOG2(level, request_id, log_ifname, log_con_uuid, ...) \
Packit Service b23acc
    nm_log ((level), \
Packit Service b23acc
            _NMLOG2_DOMAIN, \
Packit Service b23acc
            (log_ifname), \
Packit Service b23acc
            (log_con_uuid), \
Packit Service b23acc
            "dispatcher: (%u) " \
Packit Service b23acc
            _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
Packit Service b23acc
            (request_id) \
Packit Service b23acc
            _NM_UTILS_MACRO_REST (__VA_ARGS__))
Packit Service b23acc
Packit Service b23acc
#define _NMLOG3_DOMAIN     LOGD_DISPATCH
Packit Service b23acc
#define _NMLOG3(level, call_id, ...) \
Packit Service b23acc
	G_STMT_START { \
Packit Service b23acc
		const NMDispatcherCallId *const _call_id = (call_id); \
Packit Service b23acc
		\
Packit Service b23acc
		_NMLOG2 (level, _call_id->request_id, _call_id->log_ifname, _call_id->log_con_uuid, __VA_ARGS__); \
Packit Service b23acc
	} G_STMT_END
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
struct NMDispatcherCallId {
Packit Service b23acc
	NMDispatcherFunc callback;
Packit Service b23acc
	gpointer user_data;
Packit Service b23acc
	const char *log_ifname;
Packit Service b23acc
	const char *log_con_uuid;
Packit Service b23acc
	NMDispatcherAction action;
Packit Service b23acc
	guint idle_id;
Packit Service b23acc
	guint32 request_id;
Packit Service b23acc
	char extra_strings[];
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
/* FIXME(shutdown): on shutdown, we should not run dispatcher scripts synchronously.
Packit Service b23acc
 *   Instead, we should of course still run them asynchronously.
Packit Service b23acc
 *
Packit Service b23acc
 *   Also, we should wait for all pending requests to complete before exiting the main-loop
Packit Service b23acc
 *   (with a watchdog). If we hit a timeout, we log a warning and quit (but leave the scripts
Packit Service b23acc
 *   running).
Packit Service b23acc
 *
Packit Service b23acc
 *   Finally, cleanup the global structures. */
Packit Service b23acc
static struct {
Packit Service b23acc
	GDBusConnection *dbus_connection;
Packit Service b23acc
	GHashTable *requests;
Packit Service b23acc
	guint request_id_counter;
Packit Service b23acc
} gl;
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static NMDispatcherCallId *
Packit Service b23acc
dispatcher_call_id_new (guint32 request_id,
Packit Service b23acc
                        NMDispatcherAction action,
Packit Service b23acc
                        NMDispatcherFunc callback,
Packit Service b23acc
                        gpointer user_data,
Packit Service b23acc
                        const char *log_ifname,
Packit Service b23acc
                        const char *log_con_uuid)
Packit Service b23acc
{
Packit Service b23acc
	NMDispatcherCallId *call_id;
Packit Service b23acc
	gsize l_log_ifname;
Packit Service b23acc
	gsize l_log_con_uuid;
Packit Service b23acc
	char *extra_strings;
Packit Service b23acc
Packit Service b23acc
	l_log_ifname   = log_ifname   ? (strlen (log_ifname)   + 1) : 0u;
Packit Service b23acc
	l_log_con_uuid = log_con_uuid ? (strlen (log_con_uuid) + 1) : 0u;
Packit Service b23acc
Packit Service b23acc
	call_id = g_malloc (sizeof (NMDispatcherCallId) + l_log_ifname + l_log_con_uuid);
Packit Service b23acc
Packit Service b23acc
	call_id->action       = action;
Packit Service b23acc
	call_id->request_id   = request_id;
Packit Service b23acc
	call_id->callback     = callback;
Packit Service b23acc
	call_id->user_data    = user_data;
Packit Service b23acc
	call_id->idle_id      = 0;
Packit Service b23acc
Packit Service b23acc
	extra_strings = &call_id->extra_strings[0];
Packit Service b23acc
Packit Service b23acc
	if (log_ifname) {
Packit Service b23acc
		call_id->log_ifname = extra_strings;
Packit Service b23acc
		memcpy (extra_strings, log_ifname, l_log_ifname);
Packit Service b23acc
		extra_strings += l_log_ifname;
Packit Service b23acc
	} else
Packit Service b23acc
		call_id->log_ifname = NULL;
Packit Service b23acc
Packit Service b23acc
	if (log_con_uuid) {
Packit Service b23acc
		call_id->log_con_uuid = extra_strings;
Packit Service b23acc
		memcpy (extra_strings, log_con_uuid, l_log_con_uuid);
Packit Service b23acc
	} else
Packit Service b23acc
		call_id->log_con_uuid = NULL;
Packit Service b23acc
Packit Service b23acc
	return call_id;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dispatcher_call_id_free (NMDispatcherCallId *call_id)
Packit Service b23acc
{
Packit Service b23acc
	nm_clear_g_source (&call_id->idle_id);
Packit Service b23acc
	g_free (call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
_init_dispatcher (void)
Packit Service b23acc
{
Packit Service b23acc
	if (G_UNLIKELY (gl.requests == NULL)) {
Packit Service b23acc
		gl.requests = g_hash_table_new (nm_direct_hash, NULL);
Packit Service b23acc
		gl.dbus_connection = nm_g_object_ref (NM_MAIN_DBUS_CONNECTION_GET);
Packit Service b23acc
Packit Service b23acc
		if (!gl.dbus_connection)
Packit Service b23acc
			_LOGD ("No D-Bus connection to talk with NetworkManager-dispatcher service");
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dump_proxy_to_props (NMProxyConfig *proxy, GVariantBuilder *builder)
Packit Service b23acc
{
Packit Service b23acc
	const char *pac_url = NULL, *pac_script = NULL;
Packit Service b23acc
Packit Service b23acc
	if (nm_proxy_config_get_method (proxy) == NM_PROXY_CONFIG_METHOD_NONE)
Packit Service b23acc
		return;
Packit Service b23acc
Packit Service b23acc
	pac_url = nm_proxy_config_get_pac_url (proxy);
Packit Service b23acc
	if (pac_url) {
Packit Service b23acc
		g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
		                       "pac-url",
Packit Service b23acc
		                       g_variant_new_string (pac_url));
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	pac_script = nm_proxy_config_get_pac_script (proxy);
Packit Service b23acc
	if (pac_script) {
Packit Service b23acc
		g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
		                       "pac-script",
Packit Service b23acc
		                       g_variant_new_string (pac_script));
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
Packit Service b23acc
{
Packit Service b23acc
	GVariantBuilder int_builder;
Packit Service b23acc
	NMDedupMultiIter ipconf_iter;
Packit Service b23acc
	gboolean first;
Packit Service b23acc
	guint n, i;
Packit Service b23acc
	const NMPlatformIP4Address *addr;
Packit Service b23acc
	const NMPlatformIP4Route *route;
Packit Service b23acc
	guint32 array[4];
Packit Service b23acc
Packit Service b23acc
	/* Addresses */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
Packit Service b23acc
	first = TRUE;
Packit Service b23acc
	nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr) {
Packit Service b23acc
		const NMPObject *default_route;
Packit Service b23acc
Packit Service b23acc
		array[0] = addr->address;
Packit Service b23acc
		array[1] = addr->plen;
Packit Service b23acc
		array[2] = (   first
Packit Service b23acc
		            && (default_route = nm_ip4_config_best_default_route_get (ip4)))
Packit Service b23acc
		           ? NMP_OBJECT_CAST_IP4_ROUTE (default_route)->gateway
Packit Service b23acc
		           : (guint32) 0;
Packit Service b23acc
		g_variant_builder_add (&int_builder, "@au",
Packit Service b23acc
		                       g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
Packit Service b23acc
		                                                  array, 3, sizeof (guint32)));
Packit Service b23acc
		first = FALSE;
Packit Service b23acc
	}
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "addresses",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* DNS servers */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au"));
Packit Service b23acc
	n = nm_ip4_config_get_num_nameservers (ip4);
Packit Service b23acc
	for (i = 0; i < n; i++)
Packit Service b23acc
		g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_nameserver (ip4, i));
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "nameservers",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* Search domains */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as"));
Packit Service b23acc
	n = nm_ip4_config_get_num_domains (ip4);
Packit Service b23acc
	for (i = 0; i < n; i++)
Packit Service b23acc
		g_variant_builder_add (&int_builder, "s", nm_ip4_config_get_domain (ip4, i));
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "domains",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* WINS servers */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au"));
Packit Service b23acc
	n = nm_ip4_config_get_num_wins (ip4);
Packit Service b23acc
	for (i = 0; i < n; i++)
Packit Service b23acc
		g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_wins (ip4, i));
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "wins-servers",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* Static routes */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
Packit Service b23acc
	nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
Packit Service b23acc
		if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
Packit Service b23acc
			continue;
Packit Service b23acc
		array[0] = route->network;
Packit Service b23acc
		array[1] = route->plen;
Packit Service b23acc
		array[2] = route->gateway;
Packit Service b23acc
		array[3] = route->metric;
Packit Service b23acc
		g_variant_builder_add (&int_builder, "@au",
Packit Service b23acc
		                       g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
Packit Service b23acc
		                                                  array, 4, sizeof (guint32)));
Packit Service b23acc
	}
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "routes",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
Packit Service b23acc
{
Packit Service b23acc
	GVariantBuilder int_builder;
Packit Service b23acc
	NMDedupMultiIter ipconf_iter;
Packit Service b23acc
	guint n, i;
Packit Service b23acc
	gboolean first;
Packit Service b23acc
	const NMPlatformIP6Address *addr;
Packit Service b23acc
	const NMPlatformIP6Route *route;
Packit Service b23acc
	GVariant *ip, *gw;
Packit Service b23acc
Packit Service b23acc
	/* Addresses */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuay)"));
Packit Service b23acc
Packit Service b23acc
	first = TRUE;
Packit Service b23acc
	nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr) {
Packit Service b23acc
		const NMPObject *default_route;
Packit Service b23acc
Packit Service b23acc
		ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
Packit Service b23acc
		                                &addr->address,
Packit Service b23acc
		                                sizeof (struct in6_addr), 1);
Packit Service b23acc
		gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
Packit Service b23acc
		                                (   first
Packit Service b23acc
		                                 && (default_route = nm_ip6_config_best_default_route_get (ip6)))
Packit Service b23acc
		                                  ? &NMP_OBJECT_CAST_IP6_ROUTE (default_route)->gateway
Packit Service b23acc
		                                  : &in6addr_any,
Packit Service b23acc
		                                sizeof (struct in6_addr), 1);
Packit Service b23acc
		g_variant_builder_add (&int_builder, "(@ayu@ay)", ip, addr->plen, gw);
Packit Service b23acc
		first = FALSE;
Packit Service b23acc
	}
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "addresses",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* DNS servers */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aay"));
Packit Service b23acc
	n = nm_ip6_config_get_num_nameservers (ip6);
Packit Service b23acc
	for (i = 0; i < n; i++) {
Packit Service b23acc
		ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
Packit Service b23acc
		                                nm_ip6_config_get_nameserver (ip6, i),
Packit Service b23acc
		                                sizeof (struct in6_addr), 1);
Packit Service b23acc
		g_variant_builder_add (&int_builder, "@ay", ip);
Packit Service b23acc
	}
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "nameservers",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* Search domains */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as"));
Packit Service b23acc
	n = nm_ip6_config_get_num_domains (ip6);
Packit Service b23acc
	for (i = 0; i < n; i++)
Packit Service b23acc
		g_variant_builder_add (&int_builder, "s", nm_ip6_config_get_domain (ip6, i));
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "domains",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
Packit Service b23acc
	/* Static routes */
Packit Service b23acc
	g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)"));
Packit Service b23acc
	nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
Packit Service b23acc
		if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
Packit Service b23acc
			continue;
Packit Service b23acc
		ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
Packit Service b23acc
		                                &route->network,
Packit Service b23acc
		                                sizeof (struct in6_addr), 1);
Packit Service b23acc
		gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
Packit Service b23acc
		                                &route->gateway,
Packit Service b23acc
		                                sizeof (struct in6_addr), 1);
Packit Service b23acc
		g_variant_builder_add (&int_builder, "(@ayu@ayu)", ip, route->plen, gw, route->metric);
Packit Service b23acc
	}
Packit Service b23acc
	g_variant_builder_add (builder, "{sv}",
Packit Service b23acc
	                       "routes",
Packit Service b23acc
	                       g_variant_builder_end (&int_builder));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
fill_device_props (NMDevice *device,
Packit Service b23acc
                   GVariantBuilder *dev_builder,
Packit Service b23acc
                   GVariantBuilder *proxy_builder,
Packit Service b23acc
                   GVariantBuilder *ip4_builder,
Packit Service b23acc
                   GVariantBuilder *ip6_builder,
Packit Service b23acc
                   GVariant **dhcp4_props,
Packit Service b23acc
                   GVariant **dhcp6_props)
Packit Service b23acc
{
Packit Service b23acc
	NMProxyConfig *proxy_config;
Packit Service b23acc
	NMIP4Config *ip4_config;
Packit Service b23acc
	NMIP6Config *ip6_config;
Packit Service b23acc
	NMDhcpConfig *dhcp_config;
Packit Service b23acc
Packit Service b23acc
	/* If the action is for a VPN, send the VPN's IP interface instead of the device's */
Packit Service b23acc
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_IP_INTERFACE,
Packit Service b23acc
	                       g_variant_new_string (nm_device_get_ip_iface (device)));
Packit Service b23acc
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_INTERFACE,
Packit Service b23acc
	                       g_variant_new_string (nm_device_get_iface (device)));
Packit Service b23acc
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_TYPE,
Packit Service b23acc
	                       g_variant_new_uint32 (nm_device_get_device_type (device)));
Packit Service b23acc
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_STATE,
Packit Service b23acc
	                       g_variant_new_uint32 (nm_device_get_state (device)));
Packit Service b23acc
	if (nm_dbus_object_is_exported (NM_DBUS_OBJECT (device))) {
Packit Service b23acc
		g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH,
Packit Service b23acc
		                       g_variant_new_object_path (nm_dbus_object_get_path (NM_DBUS_OBJECT (device))));
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	proxy_config = nm_device_get_proxy_config (device);
Packit Service b23acc
	if (proxy_config)
Packit Service b23acc
		dump_proxy_to_props (proxy_config, proxy_builder);
Packit Service b23acc
Packit Service b23acc
	ip4_config = nm_device_get_ip4_config (device);
Packit Service b23acc
	if (ip4_config)
Packit Service b23acc
		dump_ip4_to_props (ip4_config, ip4_builder);
Packit Service b23acc
Packit Service b23acc
	ip6_config = nm_device_get_ip6_config (device);
Packit Service b23acc
	if (ip6_config)
Packit Service b23acc
		dump_ip6_to_props (ip6_config, ip6_builder);
Packit Service b23acc
Packit Service b23acc
	dhcp_config = nm_device_get_dhcp_config (device, AF_INET);
Packit Service b23acc
	if (dhcp_config)
Packit Service b23acc
		*dhcp4_props = nm_g_variant_ref (nm_dhcp_config_get_options (dhcp_config));
Packit Service b23acc
Packit Service b23acc
	dhcp_config = nm_device_get_dhcp_config (device, AF_INET6);
Packit Service b23acc
	if (dhcp_config)
Packit Service b23acc
		*dhcp6_props = nm_g_variant_ref (nm_dhcp_config_get_options (dhcp_config));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
fill_vpn_props (NMProxyConfig *proxy_config,
Packit Service b23acc
                NMIP4Config *ip4_config,
Packit Service b23acc
                NMIP6Config *ip6_config,
Packit Service b23acc
                GVariantBuilder *proxy_builder,
Packit Service b23acc
                GVariantBuilder *ip4_builder,
Packit Service b23acc
                GVariantBuilder *ip6_builder)
Packit Service b23acc
{
Packit Service b23acc
	if (proxy_config)
Packit Service b23acc
		dump_proxy_to_props (proxy_config, proxy_builder);
Packit Service b23acc
	if (ip4_config)
Packit Service b23acc
		dump_ip4_to_props (ip4_config, ip4_builder);
Packit Service b23acc
	if (ip6_config)
Packit Service b23acc
		dump_ip6_to_props (ip6_config, ip6_builder);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static const char *
Packit Service b23acc
dispatch_result_to_string (DispatchResult result)
Packit Service b23acc
{
Packit Service b23acc
	switch (result) {
Packit Service b23acc
	case DISPATCH_RESULT_UNKNOWN:
Packit Service b23acc
		return "unknown";
Packit Service b23acc
	case DISPATCH_RESULT_SUCCESS:
Packit Service b23acc
		return "success";
Packit Service b23acc
	case DISPATCH_RESULT_EXEC_FAILED:
Packit Service b23acc
		return "exec failed";
Packit Service b23acc
	case DISPATCH_RESULT_FAILED:
Packit Service b23acc
		return "failed";
Packit Service b23acc
	case DISPATCH_RESULT_TIMEOUT:
Packit Service b23acc
		return "timed out";
Packit Service b23acc
	}
Packit Service b23acc
	g_assert_not_reached ();
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dispatcher_results_process (guint32 request_id,
Packit Service b23acc
                            const char *log_ifname,
Packit Service b23acc
                            const char *log_con_uuid,
Packit Service b23acc
                            GVariant *v_results)
Packit Service b23acc
{
Packit Service b23acc
	nm_auto_free_variant_iter GVariantIter *results = NULL;
Packit Service b23acc
	const char *script, *err;
Packit Service b23acc
	guint32 result;
Packit Service b23acc
Packit Service b23acc
	g_variant_get (v_results, "(a(sus))", &results);
Packit Service b23acc
Packit Service b23acc
	if (g_variant_iter_n_children (results) == 0) {
Packit Service b23acc
		_LOG2D (request_id, log_ifname, log_con_uuid, "succeeded but no scripts invoked");
Packit Service b23acc
		return;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	while (g_variant_iter_next (results, "(&su&s)", &script, &result, &err)) {
Packit Service b23acc
		if (result == DISPATCH_RESULT_SUCCESS) {
Packit Service b23acc
			_LOG2D (request_id, log_ifname, log_con_uuid, "%s succeeded", script);
Packit Service b23acc
		} else {
Packit Service b23acc
			_LOG2W (request_id,
Packit Service b23acc
			        log_ifname,
Packit Service b23acc
			        log_con_uuid,
Packit Service b23acc
			        "%s failed (%s): %s",
Packit Service b23acc
			        script,
Packit Service b23acc
			        dispatch_result_to_string (result),
Packit Service b23acc
			        err);
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dispatcher_done_cb (GObject *source, GAsyncResult *result, gpointer user_data)
Packit Service b23acc
{
Packit Service b23acc
	gs_unref_variant GVariant *ret = NULL;
Packit Service b23acc
	gs_free_error GError *error = NULL;
Packit Service b23acc
	NMDispatcherCallId *call_id = user_data;
Packit Service b23acc
Packit Service b23acc
	nm_assert ((gpointer) source == gl.dbus_connection);
Packit Service b23acc
Packit Service b23acc
	ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
Packit Service b23acc
	                                     result,
Packit Service b23acc
	                                     &error);
Packit Service b23acc
	if (!ret) {
Packit Service b23acc
		if (_nm_dbus_error_has_name (error, "org.freedesktop.systemd1.LoadFailed")) {
Packit Service b23acc
			g_dbus_error_strip_remote_error (error);
Packit Service b23acc
			_LOG3W (call_id, "failed to call dispatcher scripts: %s",
Packit Service b23acc
			        error->message);
Packit Service b23acc
		} else {
Packit Service b23acc
			_LOG3D (call_id, "failed to call dispatcher scripts: %s",
Packit Service b23acc
			        error->message);
Packit Service b23acc
		}
Packit Service b23acc
	} else {
Packit Service b23acc
		dispatcher_results_process (call_id->request_id,
Packit Service b23acc
		                            call_id->log_ifname,
Packit Service b23acc
		                            call_id->log_con_uuid,
Packit Service b23acc
		                            ret);
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	g_hash_table_remove (gl.requests, call_id);
Packit Service b23acc
Packit Service b23acc
	if (call_id->callback)
Packit Service b23acc
		call_id->callback (call_id, call_id->user_data);
Packit Service b23acc
Packit Service b23acc
	dispatcher_call_id_free (call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static const char *action_table[] = {
Packit Service b23acc
	[NM_DISPATCHER_ACTION_HOSTNAME]     = NMD_ACTION_HOSTNAME,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_PRE_UP]       = NMD_ACTION_PRE_UP,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_UP]           = NMD_ACTION_UP,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_PRE_DOWN]     = NMD_ACTION_PRE_DOWN,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_DOWN]         = NMD_ACTION_DOWN,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_VPN_PRE_UP]   = NMD_ACTION_VPN_PRE_UP,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_VPN_UP]       = NMD_ACTION_VPN_UP,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_VPN_PRE_DOWN] = NMD_ACTION_VPN_PRE_DOWN,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_VPN_DOWN]     = NMD_ACTION_VPN_DOWN,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE,
Packit Service b23acc
	[NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
static const char *
Packit Service b23acc
action_to_string (NMDispatcherAction action)
Packit Service b23acc
{
Packit Service b23acc
	if (G_UNLIKELY ((gsize) action >= G_N_ELEMENTS (action_table)))
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
	return action_table[(gsize) action];
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
_dispatcher_call (NMDispatcherAction action,
Packit Service b23acc
                  gboolean blocking,
Packit Service b23acc
                  NMDevice *device,
Packit Service b23acc
                  NMSettingsConnection *settings_connection,
Packit Service b23acc
                  NMConnection *applied_connection,
Packit Service b23acc
                  gboolean activation_type_external,
Packit Service b23acc
                  NMConnectivityState connectivity_state,
Packit Service b23acc
                  const char *vpn_iface,
Packit Service b23acc
                  NMProxyConfig *vpn_proxy_config,
Packit Service b23acc
                  NMIP4Config *vpn_ip4_config,
Packit Service b23acc
                  NMIP6Config *vpn_ip6_config,
Packit Service b23acc
                  NMDispatcherFunc callback,
Packit Service b23acc
                  gpointer user_data,
Packit Service b23acc
                  NMDispatcherCallId **out_call_id)
Packit Service b23acc
{
Packit Service b23acc
	GVariant *connection_dict;
Packit Service b23acc
	GVariantBuilder connection_props;
Packit Service b23acc
	GVariantBuilder device_props;
Packit Service b23acc
	GVariantBuilder device_proxy_props;
Packit Service b23acc
	GVariantBuilder device_ip4_props;
Packit Service b23acc
	GVariantBuilder device_ip6_props;
Packit Service b23acc
	gs_unref_variant GVariant *parameters_floating = NULL;
Packit Service b23acc
	gs_unref_variant GVariant *device_dhcp4_props = NULL;
Packit Service b23acc
	gs_unref_variant GVariant *device_dhcp6_props = NULL;
Packit Service b23acc
	GVariantBuilder vpn_proxy_props;
Packit Service b23acc
	GVariantBuilder vpn_ip4_props;
Packit Service b23acc
	GVariantBuilder vpn_ip6_props;
Packit Service b23acc
	NMDispatcherCallId *call_id;
Packit Service b23acc
	guint request_id;
Packit Service b23acc
	const char *connectivity_state_string = "UNKNOWN";
Packit Service b23acc
	const char *log_ifname;
Packit Service b23acc
	const char *log_con_uuid;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (!blocking || (!callback && !user_data), FALSE);
Packit Service b23acc
Packit Service b23acc
	NM_SET_OUT (out_call_id, NULL);
Packit Service b23acc
Packit Service b23acc
	_init_dispatcher ();
Packit Service b23acc
Packit Service b23acc
	if (!gl.dbus_connection)
Packit Service b23acc
		return FALSE;
Packit Service b23acc
Packit Service b23acc
	log_ifname = device ? nm_device_get_iface (device) : NULL;
Packit Service b23acc
	log_con_uuid = settings_connection ? nm_settings_connection_get_uuid (settings_connection) : NULL;
Packit Service b23acc
Packit Service b23acc
	request_id = ++gl.request_id_counter;
Packit Service b23acc
	if (G_UNLIKELY (!request_id))
Packit Service b23acc
		request_id = ++gl.request_id_counter;
Packit Service b23acc
Packit Service b23acc
	/* All actions except 'hostname' and 'connectivity-change' require a device */
Packit Service b23acc
	if (   action == NM_DISPATCHER_ACTION_HOSTNAME
Packit Service b23acc
	    || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
Packit Service b23acc
		_LOG2D (request_id,
Packit Service b23acc
		        log_ifname,
Packit Service b23acc
		        log_con_uuid,
Packit Service b23acc
		        "dispatching action '%s'%s",
Packit Service b23acc
		        action_to_string (action),
Packit Service b23acc
		        blocking
Packit Service b23acc
		           ? " (blocking)"
Packit Service b23acc
		           : (callback ? " (with callback)" : ""));
Packit Service b23acc
	} else {
Packit Service b23acc
		g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
Packit Service b23acc
Packit Service b23acc
		_LOG2D (request_id,
Packit Service b23acc
		        log_ifname,
Packit Service b23acc
		        log_con_uuid,
Packit Service b23acc
		        "(%s) dispatching action '%s'%s",
Packit Service b23acc
		        vpn_iface ?: nm_device_get_iface (device),
Packit Service b23acc
		        action_to_string (action),
Packit Service b23acc
		          blocking
Packit Service b23acc
		        ? " (blocking)"
Packit Service b23acc
		        : (callback ? " (with callback)" : ""));
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (applied_connection)
Packit Service b23acc
		connection_dict = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
Packit Service b23acc
	else
Packit Service b23acc
		connection_dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
Packit Service b23acc
Packit Service b23acc
	g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	if (settings_connection) {
Packit Service b23acc
		const char *connection_path;
Packit Service b23acc
		const char *filename;
Packit Service b23acc
Packit Service b23acc
		connection_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (settings_connection));
Packit Service b23acc
		if (connection_path) {
Packit Service b23acc
			g_variant_builder_add (&connection_props, "{sv}",
Packit Service b23acc
			                       NMD_CONNECTION_PROPS_PATH,
Packit Service b23acc
			                       g_variant_new_object_path (connection_path));
Packit Service b23acc
		}
Packit Service b23acc
		filename = nm_settings_connection_get_filename (settings_connection);
Packit Service b23acc
		if (filename) {
Packit Service b23acc
			g_variant_builder_add (&connection_props, "{sv}",
Packit Service b23acc
			                       NMD_CONNECTION_PROPS_FILENAME,
Packit Service b23acc
			                       g_variant_new_string (filename));
Packit Service b23acc
		}
Packit Service b23acc
		if (activation_type_external) {
Packit Service b23acc
			g_variant_builder_add (&connection_props, "{sv}",
Packit Service b23acc
			                       NMD_CONNECTION_PROPS_EXTERNAL,
Packit Service b23acc
			                       g_variant_new_boolean (TRUE));
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&device_proxy_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&vpn_proxy_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
	g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);
Packit Service b23acc
Packit Service b23acc
	/* hostname and connectivity-change actions don't send device data */
Packit Service b23acc
	if (   action != NM_DISPATCHER_ACTION_HOSTNAME
Packit Service b23acc
	    && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
Packit Service b23acc
		fill_device_props (device,
Packit Service b23acc
		                   &device_props,
Packit Service b23acc
		                   &device_proxy_props,
Packit Service b23acc
		                   &device_ip4_props,
Packit Service b23acc
		                   &device_ip6_props,
Packit Service b23acc
		                   &device_dhcp4_props,
Packit Service b23acc
		                   &device_dhcp6_props);
Packit Service b23acc
		if (vpn_ip4_config || vpn_ip6_config) {
Packit Service b23acc
			fill_vpn_props (vpn_proxy_config,
Packit Service b23acc
			                vpn_ip4_config,
Packit Service b23acc
			                vpn_ip6_config,
Packit Service b23acc
			                &vpn_proxy_props,
Packit Service b23acc
			                &vpn_ip4_props,
Packit Service b23acc
			                &vpn_ip6_props);
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	connectivity_state_string = nm_connectivity_state_to_string (connectivity_state);
Packit Service b23acc
Packit Service b23acc
	parameters_floating = g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)",
Packit Service b23acc
	                                     action_to_string (action),
Packit Service b23acc
	                                     connection_dict,
Packit Service b23acc
	                                     &connection_props,
Packit Service b23acc
	                                     &device_props,
Packit Service b23acc
	                                     &device_proxy_props,
Packit Service b23acc
	                                     &device_ip4_props,
Packit Service b23acc
	                                     &device_ip6_props,
Packit Service b23acc
	                                     device_dhcp4_props ?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
Packit Service b23acc
	                                     device_dhcp6_props ?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
Packit Service b23acc
	                                     connectivity_state_string,
Packit Service b23acc
	                                     vpn_iface ?: "",
Packit Service b23acc
	                                     &vpn_proxy_props,
Packit Service b23acc
	                                     &vpn_ip4_props,
Packit Service b23acc
	                                     &vpn_ip6_props,
Packit Service b23acc
	                                     nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH));
Packit Service b23acc
Packit Service b23acc
	/* Send the action to the dispatcher */
Packit Service b23acc
	if (blocking) {
Packit Service b23acc
		gs_unref_variant GVariant *ret = NULL;
Packit Service b23acc
		gs_free_error GError *error = NULL;
Packit Service b23acc
Packit Service b23acc
		ret = g_dbus_connection_call_sync (gl.dbus_connection,
Packit Service b23acc
		                                   NM_DISPATCHER_DBUS_SERVICE,
Packit Service b23acc
		                                   NM_DISPATCHER_DBUS_PATH,
Packit Service b23acc
		                                   NM_DISPATCHER_DBUS_INTERFACE,
Packit Service b23acc
		                                   "Action",
Packit Service b23acc
		                                   g_steal_pointer (&parameters_floating),
Packit Service b23acc
		                                   G_VARIANT_TYPE ("(a(sus))"),
Packit Service b23acc
		                                   G_DBUS_CALL_FLAGS_NONE,
Packit Service b23acc
		                                   CALL_TIMEOUT,
Packit Service b23acc
		                                   NULL,
Packit Service b23acc
		                                   &error);
Packit Service b23acc
		if (!ret) {
Packit Service b23acc
			g_dbus_error_strip_remote_error (error);
Packit Service b23acc
			_LOG2W (request_id, log_ifname, log_con_uuid, "failed: %s", error->message);
Packit Service b23acc
			return FALSE;
Packit Service b23acc
		}
Packit Service b23acc
		dispatcher_results_process (request_id, log_ifname, log_con_uuid, ret);
Packit Service b23acc
		return TRUE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	call_id = dispatcher_call_id_new (request_id,
Packit Service b23acc
	                                  action,
Packit Service b23acc
	                                  callback,
Packit Service b23acc
	                                  user_data,
Packit Service b23acc
	                                  log_ifname,
Packit Service b23acc
	                                  log_con_uuid);
Packit Service b23acc
Packit Service b23acc
	g_dbus_connection_call (gl.dbus_connection,
Packit Service b23acc
	                        NM_DISPATCHER_DBUS_SERVICE,
Packit Service b23acc
	                        NM_DISPATCHER_DBUS_PATH,
Packit Service b23acc
	                        NM_DISPATCHER_DBUS_INTERFACE,
Packit Service b23acc
	                        "Action",
Packit Service b23acc
	                        g_steal_pointer (&parameters_floating),
Packit Service b23acc
	                        G_VARIANT_TYPE ("(a(sus))"),
Packit Service b23acc
	                        G_DBUS_CALL_FLAGS_NONE,
Packit Service b23acc
	                        CALL_TIMEOUT,
Packit Service b23acc
	                        NULL,
Packit Service b23acc
	                        dispatcher_done_cb,
Packit Service b23acc
	                        call_id);
Packit Service b23acc
	g_hash_table_add (gl.requests, call_id);
Packit Service b23acc
	NM_SET_OUT (out_call_id, call_id);
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_hostname:
Packit Service b23acc
 * @callback: a caller-supplied callback to execute when done
Packit Service b23acc
 * @user_data: caller-supplied pointer passed to @callback
Packit Service b23acc
 * @out_call_id: on success, a call identifier which can be passed to
Packit Service b23acc
 * nm_dispatcher_call_cancel()
Packit Service b23acc
 *
Packit Service b23acc
 * This method always invokes the dispatcher action asynchronously.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_hostname (NMDispatcherFunc callback,
Packit Service b23acc
                             gpointer user_data,
Packit Service b23acc
                             NMDispatcherCallId **out_call_id)
Packit Service b23acc
{
Packit Service b23acc
	return _dispatcher_call (NM_DISPATCHER_ACTION_HOSTNAME, FALSE,
Packit Service b23acc
	                         NULL, NULL, NULL, FALSE,
Packit Service b23acc
	                         NM_CONNECTIVITY_UNKNOWN,
Packit Service b23acc
	                         NULL, NULL, NULL, NULL,
Packit Service b23acc
	                         callback, user_data, out_call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_device:
Packit Service b23acc
 * @action: the %NMDispatcherAction
Packit Service b23acc
 * @device: the #NMDevice the action applies to
Packit Service b23acc
 * @act_request: the #NMActRequest for the action. If %NULL, use the
Packit Service b23acc
 *   current request of the device.
Packit Service b23acc
 * @callback: a caller-supplied callback to execute when done
Packit Service b23acc
 * @user_data: caller-supplied pointer passed to @callback
Packit Service b23acc
 * @out_call_id: on success, a call identifier which can be passed to
Packit Service b23acc
 * nm_dispatcher_call_cancel()
Packit Service b23acc
 *
Packit Service b23acc
 * This method always invokes the device dispatcher action asynchronously.  To ignore
Packit Service b23acc
 * the result, pass %NULL to @callback.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_device (NMDispatcherAction action,
Packit Service b23acc
                           NMDevice *device,
Packit Service b23acc
                           NMActRequest *act_request,
Packit Service b23acc
                           NMDispatcherFunc callback,
Packit Service b23acc
                           gpointer user_data,
Packit Service b23acc
                           NMDispatcherCallId **out_call_id)
Packit Service b23acc
{
Packit Service b23acc
	nm_assert (NM_IS_DEVICE (device));
Packit Service b23acc
	if (!act_request) {
Packit Service b23acc
		act_request = nm_device_get_act_request (device);
Packit Service b23acc
		if (!act_request)
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (act_request)), NULL, device));
Packit Service b23acc
	return _dispatcher_call (action, FALSE,
Packit Service b23acc
	                         device,
Packit Service b23acc
	                         nm_act_request_get_settings_connection (act_request),
Packit Service b23acc
	                         nm_act_request_get_applied_connection (act_request),
Packit Service b23acc
	                         nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL,
Packit Service b23acc
	                         NM_CONNECTIVITY_UNKNOWN,
Packit Service b23acc
	                         NULL, NULL, NULL, NULL,
Packit Service b23acc
	                         callback, user_data, out_call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_device_sync():
Packit Service b23acc
 * @action: the %NMDispatcherAction
Packit Service b23acc
 * @device: the #NMDevice the action applies to
Packit Service b23acc
 * @act_request: the #NMActRequest for the action. If %NULL, use the
Packit Service b23acc
 *   current request of the device.
Packit Service b23acc
 *
Packit Service b23acc
 * This method always invokes the dispatcher action synchronously and it may
Packit Service b23acc
 * take a long time to return.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_device_sync (NMDispatcherAction action,
Packit Service b23acc
                                NMDevice *device,
Packit Service b23acc
                                NMActRequest *act_request)
Packit Service b23acc
{
Packit Service b23acc
	nm_assert (NM_IS_DEVICE (device));
Packit Service b23acc
	if (!act_request) {
Packit Service b23acc
		act_request = nm_device_get_act_request (device);
Packit Service b23acc
		if (!act_request)
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
	nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (act_request)), NULL, device));
Packit Service b23acc
	return _dispatcher_call (action, TRUE,
Packit Service b23acc
	                         device,
Packit Service b23acc
	                         nm_act_request_get_settings_connection (act_request),
Packit Service b23acc
	                         nm_act_request_get_applied_connection (act_request),
Packit Service b23acc
	                         nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL,
Packit Service b23acc
	                         NM_CONNECTIVITY_UNKNOWN,
Packit Service b23acc
	                         NULL, NULL, NULL, NULL,
Packit Service b23acc
	                         NULL, NULL, NULL);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_vpn():
Packit Service b23acc
 * @action: the %NMDispatcherAction
Packit Service b23acc
 * @settings_connection: the #NMSettingsConnection the action applies to
Packit Service b23acc
 * @applied_connection: the currently applied connection
Packit Service b23acc
 * @parent_device: the parent #NMDevice of the VPN connection
Packit Service b23acc
 * @vpn_iface: the IP interface of the VPN tunnel, if any
Packit Service b23acc
 * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
Packit Service b23acc
 * @vpn_ip4_config: the #NMIP4Config of the VPN connection
Packit Service b23acc
 * @vpn_ip6_config: the #NMIP6Config of the VPN connection
Packit Service b23acc
 * @callback: a caller-supplied callback to execute when done
Packit Service b23acc
 * @user_data: caller-supplied pointer passed to @callback
Packit Service b23acc
 * @out_call_id: on success, a call identifier which can be passed to
Packit Service b23acc
 * nm_dispatcher_call_cancel()
Packit Service b23acc
 *
Packit Service b23acc
 * This method always invokes the dispatcher action asynchronously.  To ignore
Packit Service b23acc
 * the result, pass %NULL to @callback.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_vpn (NMDispatcherAction action,
Packit Service b23acc
                        NMSettingsConnection *settings_connection,
Packit Service b23acc
                        NMConnection *applied_connection,
Packit Service b23acc
                        NMDevice *parent_device,
Packit Service b23acc
                        const char *vpn_iface,
Packit Service b23acc
                        NMProxyConfig *vpn_proxy_config,
Packit Service b23acc
                        NMIP4Config *vpn_ip4_config,
Packit Service b23acc
                        NMIP6Config *vpn_ip6_config,
Packit Service b23acc
                        NMDispatcherFunc callback,
Packit Service b23acc
                        gpointer user_data,
Packit Service b23acc
                        NMDispatcherCallId **out_call_id)
Packit Service b23acc
{
Packit Service b23acc
	return _dispatcher_call (action, FALSE,
Packit Service b23acc
	                         parent_device,
Packit Service b23acc
	                         settings_connection,
Packit Service b23acc
	                         applied_connection,
Packit Service b23acc
	                         FALSE,
Packit Service b23acc
	                         NM_CONNECTIVITY_UNKNOWN,
Packit Service b23acc
	                         vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config,
Packit Service b23acc
	                         callback, user_data, out_call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_vpn_sync():
Packit Service b23acc
 * @action: the %NMDispatcherAction
Packit Service b23acc
 * @settings_connection: the #NMSettingsConnection the action applies to
Packit Service b23acc
 * @applied_connection: the currently applied connection
Packit Service b23acc
 * @parent_device: the parent #NMDevice of the VPN connection
Packit Service b23acc
 * @vpn_iface: the IP interface of the VPN tunnel, if any
Packit Service b23acc
 * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
Packit Service b23acc
 * @vpn_ip4_config: the #NMIP4Config of the VPN connection
Packit Service b23acc
 * @vpn_ip6_config: the #NMIP6Config of the VPN connection
Packit Service b23acc
 *
Packit Service b23acc
 * This method always invokes the dispatcher action synchronously and it may
Packit Service b23acc
 * take a long time to return.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_vpn_sync (NMDispatcherAction action,
Packit Service b23acc
                             NMSettingsConnection *settings_connection,
Packit Service b23acc
                             NMConnection *applied_connection,
Packit Service b23acc
                             NMDevice *parent_device,
Packit Service b23acc
                             const char *vpn_iface,
Packit Service b23acc
                             NMProxyConfig *vpn_proxy_config,
Packit Service b23acc
                             NMIP4Config *vpn_ip4_config,
Packit Service b23acc
                             NMIP6Config *vpn_ip6_config)
Packit Service b23acc
{
Packit Service b23acc
	return _dispatcher_call (action, TRUE,
Packit Service b23acc
	                         parent_device,
Packit Service b23acc
	                         settings_connection,
Packit Service b23acc
	                         applied_connection,
Packit Service b23acc
	                         FALSE,
Packit Service b23acc
	                         NM_CONNECTIVITY_UNKNOWN,
Packit Service b23acc
	                         vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config,
Packit Service b23acc
	                         NULL, NULL, NULL);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_dispatcher_call_connectivity():
Packit Service b23acc
 * @connectivity_state: the #NMConnectivityState value
Packit Service b23acc
 * @callback: a caller-supplied callback to execute when done
Packit Service b23acc
 * @user_data: caller-supplied pointer passed to @callback
Packit Service b23acc
 * @out_call_id: on success, a call identifier which can be passed to
Packit Service b23acc
 * nm_dispatcher_call_cancel()
Packit Service b23acc
 *
Packit Service b23acc
 * This method does not block the caller.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the action was dispatched, %FALSE on failure
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_dispatcher_call_connectivity (NMConnectivityState connectivity_state,
Packit Service b23acc
                                 NMDispatcherFunc callback,
Packit Service b23acc
                                 gpointer user_data,
Packit Service b23acc
                                 NMDispatcherCallId **out_call_id)
Packit Service b23acc
{
Packit Service b23acc
	return _dispatcher_call (NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, FALSE,
Packit Service b23acc
	                         NULL, NULL, NULL, FALSE,
Packit Service b23acc
	                         connectivity_state,
Packit Service b23acc
	                         NULL, NULL, NULL, NULL,
Packit Service b23acc
	                         callback, user_data, out_call_id);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
void
Packit Service b23acc
nm_dispatcher_call_cancel (NMDispatcherCallId *call_id)
Packit Service b23acc
{
Packit Service b23acc
	if (   !call_id
Packit Service b23acc
	    || g_hash_table_lookup (gl.requests, call_id) != call_id
Packit Service b23acc
	    || !call_id->callback)
Packit Service b23acc
		g_return_if_reached ();
Packit Service b23acc
Packit Service b23acc
	/* Canceling just means the callback doesn't get called, so set the
Packit Service b23acc
	 * DispatcherInfo's callback to NULL.
Packit Service b23acc
	 */
Packit Service b23acc
	_LOG3D (call_id, "cancelling dispatcher callback action");
Packit Service b23acc
	call_id->callback = NULL;
Packit Service b23acc
}