diff options
author | Dan Williams <dcbw@redhat.com> | 2014-11-13 20:32:38 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-11-13 20:32:38 -0600 |
commit | 93751847e0ca4d195daa14de42af6f38a12a8b88 (patch) | |
tree | a297df93f7baf496e37a5cdac9d084e708798648 | |
parent | e97debd887fe952953137f861a25a30500736e6b (diff) | |
parent | 226528cbaff5cdc453c3c1477894553e5eddc3c7 (diff) | |
download | NetworkManager-93751847e0ca4d195daa14de42af6f38a12a8b88.tar.gz |
Merge branch 'th/rh1098281_firewall_assumed_device' into dcbw/nm-1-0-integration
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/devices/nm-device.c | 19 | ||||
-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.c | 2 |
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)); } |