void
nm_firewall_manager_cancel_call (NMFirewallManagerCallId call)
{
	NMFirewallManager *self;
	NMFirewallManagerPrivate *priv;
	CBInfo *info = call;
	gs_free_error GError *error = NULL;

	g_return_if_fail (info);
	g_return_if_fail (NM_IS_FIREWALL_MANAGER (info->self));

	self = info->self;
	priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);

	if (!g_hash_table_remove (priv->pending_calls, info))
		g_return_if_reached ();

	nm_utils_error_set_cancelled (&error, FALSE, "NMFirewallManager");

	_LOGD (info, "complete: cancel (%s)", error->message);

	_cb_info_callback (info, error);

	if (_cb_info_is_idle (info)) {
		g_source_remove (info->idle.id);
		_cb_info_free (info);
	} else {
		info->mode = CB_INFO_MODE_DBUS_COMPLETED;
		g_cancellable_cancel (info->dbus.cancellable);
		g_clear_object (&info->self);
	}
}
static void
_cb_info_complete_normal (CBInfo *info, GError *error)
{
	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (info->self);

	if (!g_hash_table_remove (priv->pending_calls, info))
		g_return_if_reached ();

	_cb_info_callback (info, error);
	_cb_info_free (info);
}
static void
_handle_dbus (GObject *proxy, GAsyncResult *result, gpointer user_data)
{
	NMFirewallManager *self;
	CBInfo *info = user_data;
	gs_free_error GError *error = NULL;
	gs_unref_variant GVariant *ret = NULL;

	if (info->mode != CB_INFO_MODE_DBUS) {
		_cb_info_free (info);
		return;
	}

	self = info->self;

	ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error);

	if (error) {
		const char *non_error = NULL;

		g_dbus_error_strip_remote_error (error);

		switch (info->ops_type) {
		case CB_INFO_OPS_ADD:
		case CB_INFO_OPS_CHANGE:
			non_error = "ZONE_ALREADY_SET";
			break;
		case CB_INFO_OPS_REMOVE:
			non_error = "UNKNOWN_INTERFACE";
			break;
		}
		if (!g_strcmp0 (error->message, non_error)) {
			_LOGD (info, "complete: request failed with a non-error (%s)", error->message);

			/* The operation failed with an error reason that we don't want
			 * to propagate. Instead, signal success. */
			g_clear_error (&error);
		}
		else
			_LOGW (info, "complete: request failed (%s)", error->message);
	} else
		_LOGD (info, "complete: success");

	_cb_info_complete_normal (info, error);
}
static gboolean
add_or_change_idle_cb (gpointer user_data)
{
	CBInfo *info = user_data;

	if (info->idle_id == 0) {
		/* operation was cancelled. _cb_info_free will invoke callback. */
	} else {
		nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call pretends success [%u]",
		            info->iface, info->id);
		if (info->callback)
			info->callback (NULL, info->user_data);
		info->completed = TRUE;
		info->idle_id = 0;
	}

	_cb_info_free (info);
	return G_SOURCE_REMOVE;
}