summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-11-13 20:32:38 -0600
committerDan Williams <dcbw@redhat.com>2014-11-13 20:32:38 -0600
commit93751847e0ca4d195daa14de42af6f38a12a8b88 (patch)
treea297df93f7baf496e37a5cdac9d084e708798648
parente97debd887fe952953137f861a25a30500736e6b (diff)
parent226528cbaff5cdc453c3c1477894553e5eddc3c7 (diff)
downloadNetworkManager-93751847e0ca4d195daa14de42af6f38a12a8b88.tar.gz
Merge branch 'th/rh1098281_firewall_assumed_device' into dcbw/nm-1-0-integration
-rw-r--r--src/Makefile.am5
-rw-r--r--src/devices/nm-device.c19
-rw-r--r--src/nm-firewall-manager.c (renamed from src/firewall-manager/nm-firewall-manager.c)161
-rw-r--r--src/nm-firewall-manager.h (renamed from src/firewall-manager/nm-firewall-manager.h)27
-rw-r--r--src/nm-policy.c2
5 files changed, 157 insertions, 57 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eb5c64c089..a317705110 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -210,9 +210,6 @@ nm_sources = \
dnsmasq-manager/nm-dnsmasq-utils.c \
dnsmasq-manager/nm-dnsmasq-utils.h \
\
- firewall-manager/nm-firewall-manager.c \
- firewall-manager/nm-firewall-manager.h \
- \
platform/nm-fake-platform.c \
platform/nm-fake-platform.h \
platform/nm-linux-platform.c \
@@ -304,6 +301,8 @@ nm_sources = \
nm-dispatcher.h \
nm-enum-types.c \
nm-enum-types.h \
+ nm-firewall-manager.c \
+ nm-firewall-manager.h \
nm-ip4-config.c \
nm-ip4-config.h \
nm-ip6-config.c \
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 36e7dc4f10..6c6c49d6f3 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -260,7 +260,7 @@ typedef struct {
gulong dnsmasq_state_id;
/* Firewall */
- DBusGProxyCall *fw_call;
+ NMFirewallPendingCall fw_call;
/* avahi-autoipd stuff */
GPid aipd_pid;
@@ -4541,8 +4541,14 @@ out:
static void
fw_change_zone_cb (GError *error, gpointer user_data)
{
- NMDevice *self = NM_DEVICE (user_data);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMDevice *self;
+ NMDevicePrivate *priv;
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_DEVICE (user_data);
+ priv = NM_DEVICE_GET_PRIVATE (self);
priv->fw_call = NULL;
@@ -4551,7 +4557,6 @@ fw_change_zone_cb (GError *error, gpointer user_data)
}
activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0);
-
_LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled.");
}
@@ -4573,6 +4578,8 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
priv = NM_DEVICE_GET_PRIVATE (self);
g_return_if_fail (priv->act_request);
+ g_return_if_fail (!priv->fw_call);
+
/* Add the interface to the specified firewall zone */
connection = nm_device_get_connection (self);
g_assert (connection);
@@ -4584,6 +4591,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
nm_device_get_ip_iface (self),
zone,
FALSE,
+ nm_device_uses_assumed_connection (self),
fw_change_zone_cb,
self);
}
@@ -6879,7 +6887,8 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
if (deconfigure && connection) {
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
- NULL);
+ NULL,
+ nm_device_uses_assumed_connection (self));
}
ip_check_gw_ping_cleanup (self);
diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/nm-firewall-manager.c
index bb033818c6..da69272f30 100644
--- a/src/firewall-manager/nm-firewall-manager.c
+++ b/src/nm-firewall-manager.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <glib.h>
+#include <gio/gio.h>
#include <dbus/dbus.h>
#include "nm-firewall-manager.h"
@@ -46,6 +47,8 @@ typedef struct {
guint name_owner_id;
DBusGProxy * proxy;
gboolean running;
+
+ GSList *pending_calls;
} NMFirewallManagerPrivate;
enum {
@@ -58,44 +61,89 @@ static guint signals[LAST_SIGNAL] = { 0 };
/********************************************************************/
+#define PENDING_CALL_DUMMY ((NMFirewallPendingCall) ((void *) nm_firewall_manager_init) )
+#define PENDING_CALL_FROM_INFO(info) ((NMFirewallPendingCall) info)
+
typedef struct {
+ NMFirewallManager *self;
char *iface;
FwAddToZoneFunc callback;
gpointer user_data;
guint id;
gboolean completed;
+
+ gboolean cancelled;
+ gboolean is_idly_scheduled;
+ DBusGProxyCall *dbus_call;
} CBInfo;
static void
-cb_info_free (CBInfo *info)
+_cb_info_free (CBInfo *info)
{
+ NMFirewallManagerPrivate *priv;
+
g_return_if_fail (info != NULL);
- if (!info->completed)
+ if (!info->completed) {
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call cancelled [%u]", info->iface, info->id);
+ if (info->callback) {
+ GError *error;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "Operation was cancelled");
+ info->callback (error, info->user_data);
+ g_error_free (error);
+ }
+ }
g_free (info->iface);
- g_free (info);
+
+ priv = NM_FIREWALL_MANAGER_GET_PRIVATE (info->self);
+ priv->pending_calls = g_slist_remove (priv->pending_calls, info);
+ g_object_unref (info->self);
+
+ g_slice_free (CBInfo, info);
}
static CBInfo *
-_cb_info_create (const char *iface, FwAddToZoneFunc callback, gpointer user_data)
+_cb_info_create (NMFirewallManager *self, const char *iface, FwAddToZoneFunc callback, gpointer user_data)
{
+ NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
static guint id;
CBInfo *info;
- info = g_malloc (sizeof (CBInfo));
+ info = g_slice_new0 (CBInfo);
if (++id == 0)
++id;
+ info->self = g_object_ref (self);
info->id = id;
info->iface = g_strdup (iface);
info->completed = FALSE;
info->callback = callback;
info->user_data = user_data;
+ priv->pending_calls = g_slist_prepend (priv->pending_calls, info);
return info;
}
+static gboolean
+add_or_change_idle_cb (gpointer user_data)
+{
+ CBInfo *info = user_data;
+
+ if (info->cancelled) {
+ /* 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;
+ }
+
+ _cb_info_free (info);
+ return G_SOURCE_REMOVE;
+}
+
static void
add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
@@ -119,43 +167,56 @@ add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data
info->iface, info->id);
}
- info->callback (error, info->user_data);
+ if (info->callback)
+ info->callback (error, info->user_data);
info->completed = TRUE;
g_free (zone);
g_clear_error (&error);
}
-gpointer
+NMFirewallPendingCall
nm_firewall_manager_add_or_change_zone (NMFirewallManager *self,
const char *iface,
const char *zone,
gboolean add, /* TRUE == add, FALSE == change */
+ gboolean simulate_success,
FwAddToZoneFunc callback,
gpointer user_data)
{
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
CBInfo *info;
- if (priv->running == FALSE) {
- nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface);
- callback (NULL, user_data);
- return NULL;
+ if (!priv->running || simulate_success) {
+ if (callback) {
+ info = _cb_info_create (self, iface, callback, user_data);
+ info->is_idly_scheduled= TRUE;
+ g_idle_add (add_or_change_idle_cb, info);
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u] (%ssimulate success)", iface, add ? "add" : "change",
+ zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id,
+ !priv->running?"not running, ":"");
+ return PENDING_CALL_FROM_INFO (info);
+ } else {
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (%ssimulate success)", iface,
+ !priv->running?"not running, ":"");
+ return PENDING_CALL_DUMMY;
+ }
}
- info = _cb_info_create (iface, callback, user_data);
+ info = _cb_info_create (self, iface, callback, user_data);
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u]", iface, add ? "add" : "change",
zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id);
- return dbus_g_proxy_begin_call_with_timeout (priv->proxy,
- add ? "addInterface" : "changeZone",
- add_or_change_cb,
- info,
- (GDestroyNotify) cb_info_free,
- 10000, /* timeout */
- G_TYPE_STRING, zone ? zone : "",
- G_TYPE_STRING, iface,
- G_TYPE_INVALID);
+ info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
+ add ? "addInterface" : "changeZone",
+ add_or_change_cb,
+ info,
+ (GDestroyNotify) _cb_info_free,
+ 10000, /* timeout */
+ G_TYPE_STRING, zone ? zone : "",
+ G_TYPE_STRING, iface,
+ G_TYPE_INVALID);
+ return PENDING_CALL_FROM_INFO (info);
}
static void
@@ -187,39 +248,63 @@ remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
g_clear_error (&error);
}
-gpointer
+NMFirewallPendingCall
nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
const char *iface,
- const char *zone)
+ const char *zone,
+ gboolean simulate_success)
{
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
CBInfo *info;
if (priv->running == FALSE) {
- nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface);
- return NULL;
+ if (simulate_success)
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (simulate success)", iface);
+ else
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface);
+ return PENDING_CALL_DUMMY;
}
- info = _cb_info_create (iface, NULL, NULL);
+ info = _cb_info_create (self, iface, NULL, NULL);
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s%s%s [%u]", iface,
zone?"\"":"", zone ? zone : "*", zone?"\"":"", info->id);
- return dbus_g_proxy_begin_call_with_timeout (priv->proxy,
- "removeInterface",
- remove_cb,
- info,
- (GDestroyNotify) cb_info_free,
- 10000, /* timeout */
- G_TYPE_STRING, zone ? zone : "",
- G_TYPE_STRING, iface,
- G_TYPE_INVALID);
+ info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
+ "removeInterface",
+ remove_cb,
+ info,
+ (GDestroyNotify) _cb_info_free,
+ 10000, /* timeout */
+ G_TYPE_STRING, zone ? zone : "",
+ G_TYPE_STRING, iface,
+ G_TYPE_INVALID);
+ return PENDING_CALL_FROM_INFO (info);
}
-void nm_firewall_manager_cancel_call (NMFirewallManager *self, gpointer call)
+void nm_firewall_manager_cancel_call (NMFirewallManager *self, NMFirewallPendingCall call)
{
+ NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
+ GSList *pending;
+ CBInfo *info;
+
g_return_if_fail (NM_IS_FIREWALL_MANAGER (self));
- dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy,
- (DBusGProxyCall *) call);
+
+ if (call == PENDING_CALL_DUMMY)
+ return;
+
+ pending = g_slist_find (priv->pending_calls, call);
+
+ if (!pending)
+ return;
+ priv->pending_calls = g_slist_remove_link (priv->pending_calls, pending);
+
+ info = (CBInfo *) call;
+ if (info->is_idly_scheduled)
+ info->cancelled = TRUE;
+ else {
+ dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy,
+ info->dbus_call);
+ }
}
static void
diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/nm-firewall-manager.h
index 5ccbc72341..c052921246 100644
--- a/src/firewall-manager/nm-firewall-manager.h
+++ b/src/nm-firewall-manager.h
@@ -40,6 +40,9 @@ G_BEGIN_DECLS
#define NM_FIREWALL_MANAGER_AVAILABLE "available"
+struct _NMFirewallPendingCall;
+typedef struct _NMFirewallPendingCall *NMFirewallPendingCall;
+
typedef struct {
GObject parent;
} NMFirewallManager;
@@ -57,16 +60,18 @@ NMFirewallManager *nm_firewall_manager_get (void);
typedef void (*FwAddToZoneFunc) (GError *error, gpointer user_data);
-gpointer nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr,
- const char *iface,
- const char *zone,
- gboolean add,
- FwAddToZoneFunc callback,
- gpointer user_data);
-gpointer nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr,
- const char *iface,
- const char *zone);
-
-void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, gpointer fw_call);
+NMFirewallPendingCall nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr,
+ const char *iface,
+ const char *zone,
+ gboolean add,
+ gboolean simulate_success,
+ FwAddToZoneFunc callback,
+ gpointer user_data);
+NMFirewallPendingCall nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr,
+ const char *iface,
+ const char *zone,
+ gboolean simulate_success);
+
+void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, NMFirewallPendingCall fw_call);
#endif /* __NETWORKMANAGER_FIREWALL_MANAGER_H__ */
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 0a8f54e370..7a74904f81 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1581,6 +1581,7 @@ firewall_update_zone (NMPolicy *policy, NMConnection *connection)
nm_device_get_ip_iface (dev),
nm_setting_connection_get_zone (s_con),
FALSE, /* change zone */
+ nm_device_uses_assumed_connection (dev), /* simulate_success */
add_or_change_zone_cb,
g_object_ref (dev));
}
@@ -1611,6 +1612,7 @@ firewall_started (NMFirewallManager *manager,
nm_device_get_ip_iface (dev),
nm_setting_connection_get_zone (s_con),
FALSE, /* still change zone */
+ nm_device_uses_assumed_connection (dev), /* simulate_success */
add_or_change_zone_cb,
g_object_ref (dev));
}