summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-11-14 17:31:29 -0600
committerDan Williams <dcbw@redhat.com>2014-11-14 17:31:29 -0600
commit3c252294b92ac490795d5b94de64d2991dd41a1d (patch)
treea0beb5488ff9825d2c69abd0150707ca2bb162c9
parent669f74b83be6b652c712d1ecd6b8ea55a411e2ab (diff)
parent0d36f4350b84ef0a040916ba951565148a5bfb41 (diff)
downloadNetworkManager-dcbw/nm-1-0-integration-20141114.tar.gz
Merge branch 'th/rh1098281_firewall_assumed_device' into dcbw/nm-1-0-integrationdcbw/nm-1-0-integration-20141114
-rw-r--r--src/Makefile.am5
-rw-r--r--src/devices/nm-device.c27
-rw-r--r--src/nm-firewall-manager.c (renamed from src/firewall-manager/nm-firewall-manager.c)155
-rw-r--r--src/nm-firewall-manager.h (renamed from src/firewall-manager/nm-firewall-manager.h)25
-rw-r--r--src/nm-policy.c6
5 files changed, 162 insertions, 56 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 cb713971b2..3c497fae6c 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -263,7 +263,7 @@ typedef struct {
gulong dnsmasq_state_id;
/* Firewall */
- DBusGProxyCall *fw_call;
+ NMFirewallPendingCall fw_call;
/* avahi-autoipd stuff */
GPid aipd_pid;
@@ -4580,8 +4580,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;
@@ -4590,7 +4596,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.");
}
@@ -4612,12 +4617,22 @@ 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);
s_con = nm_connection_get_setting_connection (connection);
zone = nm_setting_connection_get_zone (s_con);
+
+ if (nm_device_uses_assumed_connection (self)) {
+ _LOGD (LOGD_DEVICE, "Activation: skip setting firewall zone '%s' for assumed device", zone ? zone : "default");
+ activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0);
+ _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled.");
+ return;
+ }
+
_LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default");
priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
@@ -6918,7 +6933,9 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
}
connection = nm_device_get_connection (self);
- if (deconfigure && connection) {
+ if ( deconfigure
+ && connection
+ && !nm_device_uses_assumed_connection (self)) {
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
NULL);
diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/nm-firewall-manager.c
index bb033818c6..b1248adfb9 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,94 @@ static guint signals[LAST_SIGNAL] = { 0 };
/********************************************************************/
+#define PENDING_CALL_DUMMY ((NMFirewallPendingCall) GUINT_TO_POINTER(1))
+#define PENDING_CALL_FROM_INFO(info) ((NMFirewallPendingCall) info)
+
+typedef enum {
+ IDLY_SCHEDULED_TYPE_NONE = 0,
+ IDLY_SCHEDULED_TYPE_PENDING = 1,
+ IDLY_SCHEDULED_TYPE_CANCELLED = 2,
+} IdlyScheduledType;
+
typedef struct {
+ NMFirewallManager *self;
char *iface;
FwAddToZoneFunc callback;
gpointer user_data;
guint id;
gboolean completed;
+
+ IdlyScheduledType 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->idly_scheduled == IDLY_SCHEDULED_TYPE_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,14 +172,15 @@ 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,
@@ -138,24 +192,33 @@ nm_firewall_manager_add_or_change_zone (NMFirewallManager *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 (callback) {
+ info = _cb_info_create (self, iface, callback, user_data);
+ info->idly_scheduled = IDLY_SCHEDULED_TYPE_PENDING;
+ g_idle_add (add_or_change_idle_cb, info);
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u] (not running, simulate success)", iface, add ? "add" : "change",
+ zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id);
+ return PENDING_CALL_FROM_INFO (info);
+ } else {
+ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface);
+ 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,7 +250,7 @@ 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)
@@ -197,29 +260,49 @@ nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
if (priv->running == FALSE) {
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface);
- return NULL;
+ 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->idly_scheduled != IDLY_SCHEDULED_TYPE_NONE)
+ info->idly_scheduled = IDLY_SCHEDULED_TYPE_CANCELLED;
+ else {
+ dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy,
+ info->dbus_call);
+ }
}
static void
@@ -318,6 +401,8 @@ dispose (GObject *object)
{
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (object);
+ g_assert (priv->pending_calls == NULL);
+
if (priv->dbus_mgr) {
g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
priv->name_owner_id = 0;
diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/nm-firewall-manager.h
index 5ccbc72341..84cb5498ae 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,16 @@ 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,
+ FwAddToZoneFunc callback,
+ gpointer user_data);
+NMFirewallPendingCall nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr,
+ const char *iface,
+ const char *zone);
+
+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..87fcdcc925 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1576,7 +1576,8 @@ firewall_update_zone (NMPolicy *policy, NMConnection *connection)
NMDevice *dev = NM_DEVICE (iter->data);
if ( (nm_device_get_connection (dev) == connection)
- && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) {
+ && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)
+ && !nm_device_uses_assumed_connection (dev)) {
nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (dev),
nm_setting_connection_get_zone (s_con),
@@ -1606,7 +1607,8 @@ firewall_started (NMFirewallManager *manager,
continue;
s_con = nm_connection_get_setting_connection (connection);
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
+ if ( nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED
+ && !nm_device_uses_assumed_connection (dev)) {
nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (dev),
nm_setting_connection_get_zone (s_con),