diff options
author | Dan Williams <dcbw@redhat.com> | 2014-11-14 17:31:29 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-11-14 17:31:29 -0600 |
commit | 3c252294b92ac490795d5b94de64d2991dd41a1d (patch) | |
tree | a0beb5488ff9825d2c69abd0150707ca2bb162c9 | |
parent | 669f74b83be6b652c712d1ecd6b8ea55a411e2ab (diff) | |
parent | 0d36f4350b84ef0a040916ba951565148a5bfb41 (diff) | |
download | NetworkManager-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.am | 5 | ||||
-rw-r--r-- | src/devices/nm-device.c | 27 | ||||
-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.c | 6 |
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), |