From 7085020e308094d1ed787b489f87745e069c7b15 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jun 10 2014 14:10:16 +0000 Subject: import NetworkManager-0.9.9.1-22.git20140326.4dba720.el7_0 --- diff --git a/SOURCES/0020-rh1103782-firewall-zone-conflict.patch b/SOURCES/0020-rh1103782-firewall-zone-conflict.patch new file mode 100644 index 0000000..67bdcdc --- /dev/null +++ b/SOURCES/0020-rh1103782-firewall-zone-conflict.patch @@ -0,0 +1,367 @@ +From 472dd9aa672de85b49ade5150cbb81497cb8d14d Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 2 Jun 2014 12:21:57 +0200 +Subject: [PATCH 1/5] firewall: refactor reentrancy for dispose() in + NMFirewallManager + +Signed-off-by: Thomas Haller +(cherry picked from commit dde731f0ade88c690b7cf6465c016b9d2343094b) +--- + src/firewall-manager/nm-firewall-manager.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c +index 3bf2f24..6d87391 100644 +--- a/src/firewall-manager/nm-firewall-manager.c ++++ b/src/firewall-manager/nm-firewall-manager.c +@@ -44,7 +44,6 @@ typedef struct { + guint name_owner_id; + DBusGProxy * proxy; + gboolean running; +- gboolean disposed; + } NMFirewallManagerPrivate; + + enum { +@@ -247,7 +246,7 @@ nm_firewall_manager_init (NMFirewallManager * self) + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + DBusGConnection *bus; + +- priv->dbus_mgr = nm_dbus_manager_get (); ++ priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ()); + priv->name_owner_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed), +@@ -286,20 +285,14 @@ dispose (GObject *object) + { + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (object); + +- if (priv->disposed) +- goto out; +- priv->disposed = TRUE; +- + if (priv->dbus_mgr) { +- if (priv->name_owner_id) +- g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); +- priv->dbus_mgr = NULL; ++ g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); ++ priv->name_owner_id = 0; ++ g_clear_object (&priv->dbus_mgr); + } + +- if (priv->proxy) +- g_object_unref (priv->proxy); ++ g_clear_object (&priv->proxy); + +-out: + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_firewall_manager_parent_class)->dispose (object); + } +-- +1.9.3 + + +From 3e4ab3a8860d916286ea772e85dfa0432893a6d5 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 2 Jun 2014 15:56:24 +0200 +Subject: [PATCH 2/5] firewall: refactor allocation of CBInfo data in + NMFirewallManager + +Signed-off-by: Thomas Haller +(cherry picked from commit e3605ab924dd9865ecba9a06de6f5011a9bae3e3) +--- + src/firewall-manager/nm-firewall-manager.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c +index 6d87391..52a5444 100644 +--- a/src/firewall-manager/nm-firewall-manager.c ++++ b/src/firewall-manager/nm-firewall-manager.c +@@ -70,6 +70,19 @@ cb_info_free (CBInfo *info) + g_free (info); + } + ++static CBInfo * ++_cb_info_create (const char *iface, FwAddToZoneFunc callback, gpointer user_data) ++{ ++ CBInfo *info; ++ ++ info = g_malloc0 (sizeof (CBInfo)); ++ info->iface = g_strdup (iface); ++ info->callback = callback; ++ info->user_data = user_data; ++ ++ return info; ++} ++ + static void + add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) + { +@@ -113,10 +126,7 @@ nm_firewall_manager_add_or_change_zone (NMFirewallManager *self, + return NULL; + } + +- info = g_malloc0 (sizeof (*info)); +- info->iface = g_strdup (iface); +- info->callback = callback; +- info->user_data = user_data; ++ info = _cb_info_create (iface, callback, user_data); + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s", iface, add ? "add" : "change", + zone?"\"":"", zone ? zone : "default", zone?"\"":""); +@@ -166,8 +176,7 @@ nm_firewall_manager_remove_from_zone (NMFirewallManager *self, + return NULL; + } + +- info = g_malloc0 (sizeof (*info)); +- info->iface = g_strdup (iface); ++ info = _cb_info_create (iface, NULL, NULL); + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s", iface, zone ); + return dbus_g_proxy_begin_call_with_timeout (priv->proxy, +-- +1.9.3 + + +From 28732c8a3589395975ec6113f1fe2bb925acf72c Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 2 Jun 2014 17:52:33 +0200 +Subject: [PATCH 3/5] firewall: extend logging to show id for async dbus calls + in NMFirewallManager + +Signed-off-by: Thomas Haller +(cherry picked from commit 3bc38ad531b9976577e543229125d7d8274efe82) +--- + src/firewall-manager/nm-firewall-manager.c | 43 +++++++++++++++++++++++------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c +index 52a5444..c99372a 100644 +--- a/src/firewall-manager/nm-firewall-manager.c ++++ b/src/firewall-manager/nm-firewall-manager.c +@@ -60,12 +60,18 @@ typedef struct { + char *iface; + FwAddToZoneFunc callback; + gpointer user_data; ++ guint id; ++ gboolean completed; + } CBInfo; + + static void + cb_info_free (CBInfo *info) + { + g_return_if_fail (info != NULL); ++ ++ if (!info->completed) ++ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call cancelled [%u]", info->iface, info->id); ++ + g_free (info->iface); + g_free (info); + } +@@ -73,10 +79,15 @@ cb_info_free (CBInfo *info) + static CBInfo * + _cb_info_create (const char *iface, FwAddToZoneFunc callback, gpointer user_data) + { ++ static guint id; + CBInfo *info; + +- info = g_malloc0 (sizeof (CBInfo)); ++ info = g_malloc (sizeof (CBInfo)); ++ if (++id == 0) ++ ++id; ++ info->id = id; + info->iface = g_strdup (iface); ++ info->completed = FALSE; + info->callback = callback; + info->user_data = user_data; + +@@ -95,16 +106,20 @@ add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data + G_TYPE_INVALID)) { + g_assert (error); + if (g_strcmp0 (error->message, "ZONE_ALREADY_SET") != 0) { +- nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed: (%d) %s", +- info->iface, error->code, error->message); ++ nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", ++ info->iface, info->id, error->code, error->message); + } else { +- nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed: (%d) %s", +- info->iface, error->code, error->message); ++ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", ++ info->iface, info->id, error->code, error->message); + } ++ } else { ++ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change succeeded [%u]", ++ info->iface, info->id); + } + + info->callback (error, info->user_data); + ++ info->completed = TRUE; + g_free (zone); + g_clear_error (&error); + } +@@ -128,8 +143,8 @@ nm_firewall_manager_add_or_change_zone (NMFirewallManager *self, + + info = _cb_info_create (iface, callback, user_data); + +- nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s", iface, add ? "add" : "change", +- zone?"\"":"", zone ? zone : "default", zone?"\"":""); ++ 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, +@@ -154,11 +169,18 @@ remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) + g_assert (error); + /* ignore UNKNOWN_INTERFACE errors */ + if (error->message && !strstr (error->message, "UNKNOWN_INTERFACE")) { +- nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed: (%d) %s", +- info->iface, error->code, error->message); ++ nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", ++ info->iface, info->id, error->code, error->message); ++ } else { ++ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", ++ info->iface, info->id, error->code, error->message); + } ++ } else { ++ nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove succeeded [%u]", ++ info->iface, info->id); + } + ++ info->completed = TRUE; + g_free (zone); + g_clear_error (&error); + } +@@ -178,7 +200,8 @@ nm_firewall_manager_remove_from_zone (NMFirewallManager *self, + + info = _cb_info_create (iface, NULL, NULL); + +- nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s", iface, zone ); ++ 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, +-- +1.9.3 + + +From 342f9f90dbbea28d02dd7a5058c1caea7817142c Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 2 Jun 2014 18:11:54 +0200 +Subject: [PATCH 4/5] firewall: fix ZONE_CONFLICT when removing interface from + zone + +The firewalld removeInterface call fails with ZONE_CONFLICT when +removing an interface from a wrong zone. This can happen, when the +connection gets modified, while being active (which is related to +bgo#724041). + +By not specifying any zone, we remove the interface from the zone +where it currently is added. This behavior was introduced in upstream +firewalld with commit cc3101ab70a3997228be7bc9f45a069c7fccfa36, March 2012, +r0_2_3-1. +This is the behavior we actually want and we don't have to keep proper track +of the current zone. + +https://bugzilla.redhat.com/show_bug.cgi?id=1103782 + +Signed-off-by: Thomas Haller +(cherry picked from commit c598336de8d5a257765bf415b87e2bb7a1140b7d) +--- + src/devices/nm-device.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index 8399cf6..dd0ea5a 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -4912,7 +4912,6 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) + NMDevicePrivate *priv; + NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE; + NMConnection *connection = NULL; +- NMSettingConnection *s_con = NULL; + int ifindex; + + g_return_if_fail (NM_IS_DEVICE (self)); +@@ -4937,10 +4936,9 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) + if (priv->act_request) + connection = nm_act_request_get_connection (priv->act_request); + if (connection) { +- s_con = nm_connection_get_setting_connection (connection); + nm_firewall_manager_remove_from_zone (priv->fw_manager, + nm_device_get_ip_iface (self), +- nm_setting_connection_get_zone (s_con)); ++ NULL); + } + + ip_check_gw_ping_cleanup (self); +-- +1.9.3 + + +From cda973fe9c83ea415d3178973ff7826904b2997f Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 3 Jun 2014 08:58:20 +0200 +Subject: [PATCH 5/5] firewall: fix ZONE_CONFLICT when adding firewall + interface to zone + +Firewalld call addInterface() fails with ZONE_CONFLICT if the interface +is already part of another zone. This complicates the code in NM, +because we would have to keep better track of the zone in which the +interface currently is. Which might be quite difficult because +the zone might be changed from an external program (so we would have +to monitor the firewall configuration and work around potential races). + +A better and simpler fix is to simply always use the changeZone() call. +This will do the right thing, regardless if the interface is already part +of a zone or not. + +https://bugzilla.redhat.com/show_bug.cgi?id=1103782 + +Signed-off-by: Thomas Haller +(cherry picked from commit c29388bf028d404066e46ea55abc4058abce4078) +--- + src/devices/nm-device.c | 6 +++--- + src/nm-policy.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index dd0ea5a..264d4ab 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -4023,7 +4023,7 @@ out: + + + static void +-fw_add_to_zone_cb (GError *error, gpointer user_data) ++fw_change_zone_cb (GError *error, gpointer user_data) + { + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); +@@ -4072,8 +4072,8 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) + priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_manager, + nm_device_get_ip_iface (self), + zone, +- TRUE, +- fw_add_to_zone_cb, ++ FALSE, ++ fw_change_zone_cb, + self); + } + +diff --git a/src/nm-policy.c b/src/nm-policy.c +index b412427..f064fa0 100644 +--- a/src/nm-policy.c ++++ b/src/nm-policy.c +@@ -1886,7 +1886,7 @@ firewall_started (NMFirewallManager *manager, + nm_firewall_manager_add_or_change_zone (priv->fw_manager, + nm_device_get_ip_iface (dev), + nm_setting_connection_get_zone (s_con), +- TRUE, /* add zone */ ++ FALSE, /* still change zone */ + add_or_change_zone_cb, + g_object_ref (dev)); + } +-- +1.9.3 + diff --git a/SOURCES/rh1067712-connection-order-fix.patch b/SOURCES/rh1067712-connection-order-fix.patch new file mode 100644 index 0000000..14edbb5 --- /dev/null +++ b/SOURCES/rh1067712-connection-order-fix.patch @@ -0,0 +1,55 @@ +From 583eba38280628da9c645d402483f9fd0927005a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Thu, 10 Apr 2014 13:25:41 +0200 +Subject: [PATCH] core: sort connections in descending timestamp order on + take-over (rh #1067712) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When assuming the connections on restart we want to prefer more-recently-used +connections. That's why we have to sort connections according to timestamps in +descending order. That means connections used more recently (higher timestamp) +go before connections with lower timestamp. + +https://bugzilla.redhat.com/show_bug.cgi?id=1067712 + +Signed-off-by: Jiří Klimeš +--- + src/nm-manager.c | 2 +- + src/settings/nm-settings.c | 6 +++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/nm-manager.c b/src/nm-manager.c +index d3d660c..f991b04 100644 +--- a/src/nm-manager.c ++++ b/src/nm-manager.c +@@ -1706,7 +1706,7 @@ get_existing_connection (NMManager *manager, NMDevice *device) + * When no configured connection matches the generated connection, we keep + * the generated connection instead. + */ +- connections = g_slist_sort (connections, nm_settings_sort_connections); ++ connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections)); + matched = nm_utils_match_connection (connections, + connection, + nm_device_has_carrier (device), +diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c +index 852fa6d..b4d9c22 100644 +--- a/src/settings/nm-settings.c ++++ b/src/settings/nm-settings.c +@@ -1685,7 +1685,11 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quittin + + /***************************************************************/ + +-/* GCompareFunc helper for sorting "best" connections */ ++/* GCompareFunc helper for sorting "best" connections. ++ * The function sorts connections in ascending timestamp order. ++ * That means an older connection (lower timestamp) goes before ++ * a newer one. ++ */ + gint + nm_settings_sort_connections (gconstpointer a, gconstpointer b) + { +-- +1.7.11.7 + diff --git a/SOURCES/rh1083196-ipv6-method-ignore-auto.patch b/SOURCES/rh1083196-ipv6-method-ignore-auto.patch new file mode 100644 index 0000000..ec840fb --- /dev/null +++ b/SOURCES/rh1083196-ipv6-method-ignore-auto.patch @@ -0,0 +1,191 @@ +From fbdf8857c32e016005f19ad1e0be0bddc902a6ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Thu, 29 May 2014 16:36:24 +0200 +Subject: [PATCH 1/2] core: take over connections with IPv6 method 'ignore' + for 'auto' (rh #1083196) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we had a connection with IPv6.method = ignore, we simply ignored IPv6. So +we should assume this connection even if there is an SLAAC address on the +interface. + +https://bugzilla.redhat.com/show_bug.cgi?id=1083196 + +Signed-off-by: Jiří Klimeš +--- + src/NetworkManagerUtils.c | 7 ++++--- + src/tests/test-general.c | 36 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 40 insertions(+), 3 deletions(-) + +diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c +index a3d264a..f869034 100644 +--- a/src/NetworkManagerUtils.c ++++ b/src/NetworkManagerUtils.c +@@ -707,11 +707,12 @@ check_ip6_method (NMConnection *orig, + allow = TRUE; + } + +- /* If the original connection method is 'link-local' and the candidate method +- * is 'ignore' we can take the connection, because NM didn't simply take care ++ /* If the generated connection method is 'link-local' or 'auto' and the candidate ++ * method is 'ignore' we can take the connection, because NM didn't simply take care + * of IPv6. + */ +- if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 ++ if ( ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 ++ || strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) + && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { + allow = TRUE; + } +diff --git a/src/tests/test-general.c b/src/tests/test-general.c +index d103c2b..521998b 100644 +--- a/src/tests/test-general.c ++++ b/src/tests/test-general.c +@@ -368,6 +368,41 @@ test_connection_match_ip6_method_ignore (void) + } + + static void ++test_connection_match_ip6_method_ignore_auto (void) ++{ ++ NMConnection *orig, *copy, *matched; ++ GSList *connections = NULL; ++ NMSettingIP6Config *s_ip6; ++ ++ orig = _match_connection_new (); ++ copy = nm_connection_duplicate (orig); ++ connections = g_slist_append (connections, copy); ++ ++ /* Check that if the generated connection is IPv6 method=auto, and the ++ * candidate is method=ignore, that the candidate is matched. ++ */ ++ s_ip6 = nm_connection_get_setting_ip6_config (orig); ++ g_assert (s_ip6); ++ g_object_set (G_OBJECT (s_ip6), ++ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, ++ NULL); ++ ++ s_ip6 = nm_connection_get_setting_ip6_config (copy); ++ g_assert (s_ip6); ++ g_object_set (G_OBJECT (s_ip6), ++ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, ++ NULL); ++ ++ matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); ++ g_assert (matched == copy); ++ ++ g_slist_free (connections); ++ g_object_unref (orig); ++ g_object_unref (copy); ++} ++ ++ ++static void + test_connection_match_ip4_method (void) + { + NMConnection *orig, *copy, *matched; +@@ -568,6 +603,7 @@ main (int argc, char **argv) + g_test_add_func ("/general/connection-match/basic", test_connection_match_basic); + g_test_add_func ("/general/connection-match/ip6-method", test_connection_match_ip6_method); + g_test_add_func ("/general/connection-match/ip6-method-ignore", test_connection_match_ip6_method_ignore); ++ g_test_add_func ("/general/connection-match/ip6-method-ignore-auto", test_connection_match_ip6_method_ignore_auto); + g_test_add_func ("/general/connection-match/ip4-method", test_connection_match_ip4_method); + g_test_add_func ("/general/connection-match/con-interface-name", test_connection_match_interface_name); + g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); +-- +1.7.11.7 + + +From a7fa1aed1b9ca46a2c02a39ad023ad7c1cf88baf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Fri, 30 May 2014 09:06:24 +0200 +Subject: [PATCH 2/2] trivial: clarify comments in test-general.c and + NetworkManagerUtils.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + src/NetworkManagerUtils.c | 6 +++--- + src/tests/test-general.c | 10 +++++----- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c +index f869034..4df429a 100644 +--- a/src/NetworkManagerUtils.c ++++ b/src/NetworkManagerUtils.c +@@ -691,7 +691,7 @@ check_ip6_method (NMConnection *orig, + if (!props) + return TRUE; + +- /* If the original connection is 'link-local' and the candidate is both 'auto' ++ /* If the generated connection is 'link-local' and the candidate is both 'auto' + * and may-fail=TRUE, then the candidate is OK to use. may-fail is included + * in the decision because if the candidate is 'auto' but may-fail=FALSE, then + * the connection could not possibly have been previously activated on the +@@ -741,7 +741,7 @@ check_ip4_method (NMConnection *orig, + if (!props) + return TRUE; + +- /* If the original connection is 'disabled' (device had no IP addresses) ++ /* If the generated connection is 'disabled' (device had no IP addresses) + * but it has no carrier, that most likely means that IP addressing could + * not complete and thus no IP addresses were assigned. In that case, allow + * matching to the "auto" method. +@@ -777,7 +777,7 @@ check_connection_interface_name (NMConnection *orig, + if (!props) + return TRUE; + +- /* If one of the interface name is NULL, we accept that connection */ ++ /* If one of the interface names is NULL, we accept that connection */ + s_con_orig = nm_connection_get_setting_connection (orig); + s_con_cand = nm_connection_get_setting_connection (candidate); + orig_ifname = nm_setting_connection_get_interface_name (s_con_orig); +diff --git a/src/tests/test-general.c b/src/tests/test-general.c +index 521998b..11c03f0 100644 +--- a/src/tests/test-general.c ++++ b/src/tests/test-general.c +@@ -308,7 +308,7 @@ test_connection_match_ip6_method (void) + copy = nm_connection_duplicate (orig); + connections = g_slist_append (connections, copy); + +- /* Check that if the original connection is IPv6 method=link-local, and the ++ /* Check that if the generated connection is IPv6 method=link-local, and the + * candidate is both method=auto and may-faily=true, that the candidate is + * matched. + */ +@@ -344,7 +344,7 @@ test_connection_match_ip6_method_ignore (void) + copy = nm_connection_duplicate (orig); + connections = g_slist_append (connections, copy); + +- /* Check that if the original connection is IPv6 method=link-local, and the ++ /* Check that if the generated connection is IPv6 method=link-local, and the + * candidate is method=ignore, that the candidate is matched. + */ + s_ip6 = nm_connection_get_setting_ip6_config (orig); +@@ -413,7 +413,7 @@ test_connection_match_ip4_method (void) + copy = nm_connection_duplicate (orig); + connections = g_slist_append (connections, copy); + +- /* Check that if the original connection is IPv4 method=disabled, and the ++ /* Check that if the generated connection is IPv4 method=disabled, and the + * candidate is both method=auto and may-faily=true, and the device has no + * carrier that the candidate is matched. + */ +@@ -453,8 +453,8 @@ test_connection_match_interface_name (void) + copy = nm_connection_duplicate (orig); + connections = g_slist_append (connections, copy); + +- /* Check that if the original connection is IPv6 method=link-local, and the +- * candidate is method=ignore, that the candidate is matched. ++ /* Check that if the generated connection has an interface name and the ++ * candidate's interface name is NULL, that the candidate is matched. + */ + s_con = nm_connection_get_setting_connection (orig); + g_assert (s_con); +-- +1.7.11.7 + diff --git a/SOURCES/rh1083196-match-connections-and-s390.patch b/SOURCES/rh1083196-match-connections-and-s390.patch new file mode 100644 index 0000000..c8a2b6f --- /dev/null +++ b/SOURCES/rh1083196-match-connections-and-s390.patch @@ -0,0 +1,795 @@ +From d12b2079bf6508f71a2c6088de1ea1a4d7ae9106 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Wed, 9 Apr 2014 13:48:27 +0200 +Subject: [PATCH 1/5] utils: fix check_possible_match() function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We can only allow possible match if all the differences are exceptions. +Before, we accepted the connection if an exception was found, but it is wrong +because there may be another difference (that is fatal). + +Signed-off-by: Jiří Klimeš +--- + src/NetworkManagerUtils.c | 139 ++++++++++++++++++++++++---------------------- + 1 file changed, 74 insertions(+), 65 deletions(-) + +diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c +index 17116ee..e0a232e 100644 +--- a/src/NetworkManagerUtils.c ++++ b/src/NetworkManagerUtils.c +@@ -649,22 +649,47 @@ nm_utils_read_resolv_conf_nameservers (const char *rc_contents) + return nameservers; + } + ++static GHashTable * ++check_property_in_hash (GHashTable *hash, ++ const char *s_name, ++ const char *p_name) ++{ ++ GHashTable *props; ++ ++ props = g_hash_table_lookup (hash, s_name); ++ if ( !props ++ || !g_hash_table_lookup (props, p_name)) { ++ return NULL; ++ } ++ return props; ++} ++ ++static void ++remove_from_hash (GHashTable *s_hash, ++ GHashTable *p_hash, ++ const char *s_name, ++ const char *p_name) ++{ ++ g_hash_table_remove (p_hash, p_name); ++ if (g_hash_table_size (p_hash) == 0) ++ g_hash_table_remove (s_hash, s_name); ++} ++ + static gboolean +-check_ip6_method_link_local_auto (NMConnection *orig, +- NMConnection *candidate, +- GHashTable *settings) ++check_ip6_method (NMConnection *orig, ++ NMConnection *candidate, ++ GHashTable *settings) + { + GHashTable *props; + const char *orig_ip6_method, *candidate_ip6_method; + NMSettingIP6Config *candidate_ip6; ++ gboolean allow = FALSE; + +- props = g_hash_table_lookup (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME); +- if ( !props +- || (g_hash_table_size (props) != 1) +- || !g_hash_table_lookup (props, NM_SETTING_IP6_CONFIG_METHOD)) { +- /* For now 'method' is the only difference we handle here */ +- return FALSE; +- } ++ props = check_property_in_hash (settings, ++ NM_SETTING_IP6_CONFIG_SETTING_NAME, ++ NM_SETTING_IP6_CONFIG_METHOD); ++ if (!props) ++ return TRUE; + + /* If the original connection is 'link-local' and the candidate is both 'auto' + * and may-fail=TRUE, then the candidate is OK to use. may-fail is included +@@ -679,60 +704,41 @@ check_ip6_method_link_local_auto (NMConnection *orig, + if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 + && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + && (!candidate_ip6 || nm_setting_ip6_config_get_may_fail (candidate_ip6))) { +- return TRUE; +- } +- +- return FALSE; +-} +- +-static gboolean +-check_ip6_method_link_local_ignore (NMConnection *orig, +- NMConnection *candidate, +- GHashTable *settings) +-{ +- GHashTable *props; +- const char *orig_ip6_method, *candidate_ip6_method; +- +- props = g_hash_table_lookup (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME); +- if ( !props +- || (g_hash_table_size (props) != 1) +- || !g_hash_table_lookup (props, NM_SETTING_IP6_CONFIG_METHOD)) { +- /* We only handle ipv6 'method' here */ +- return FALSE; ++ allow = TRUE; + } + + /* If the original connection method is 'link-local' and the candidate method + * is 'ignore' we can take the connection, because NM didn't simply take care + * of IPv6. + */ +- orig_ip6_method = nm_utils_get_ip_config_method (orig, NM_TYPE_SETTING_IP6_CONFIG); +- candidate_ip6_method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG); +- + if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 + && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { +- return TRUE; ++ allow = TRUE; + } + +- return FALSE; ++ if (allow) { ++ remove_from_hash (settings, props, ++ NM_SETTING_IP6_CONFIG_SETTING_NAME, ++ NM_SETTING_IP6_CONFIG_METHOD); ++ } ++ return allow; + } + + static gboolean +-check_ip4_method_disabled_auto (NMConnection *orig, +- NMConnection *candidate, +- GHashTable *settings, +- gboolean device_has_carrier) ++check_ip4_method (NMConnection *orig, ++ NMConnection *candidate, ++ GHashTable *settings, ++ gboolean device_has_carrier) + { + GHashTable *props; + const char *orig_ip4_method, *candidate_ip4_method; + NMSettingIP4Config *candidate_ip4; + +- props = g_hash_table_lookup (settings, NM_SETTING_IP4_CONFIG_SETTING_NAME); +- if ( !props +- || (g_hash_table_size (props) != 1) +- || !g_hash_table_lookup (props, NM_SETTING_IP4_CONFIG_METHOD)) { +- /* For now 'method' is the only difference we handle here */ +- return FALSE; +- } ++ props = check_property_in_hash (settings, ++ NM_SETTING_IP4_CONFIG_SETTING_NAME, ++ NM_SETTING_IP4_CONFIG_METHOD); ++ if (!props) ++ return TRUE; + + /* If the original connection is 'disabled' (device had no IP addresses) + * but it has no carrier, that most likely means that IP addressing could +@@ -747,9 +753,11 @@ check_ip4_method_disabled_auto (NMConnection *orig, + && strcmp (candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0 + && (!candidate_ip4 || nm_setting_ip4_config_get_may_fail (candidate_ip4)) + && (device_has_carrier == FALSE)) { ++ remove_from_hash (settings, props, ++ NM_SETTING_IP4_CONFIG_SETTING_NAME, ++ NM_SETTING_IP4_CONFIG_METHOD); + return TRUE; + } +- + return FALSE; + } + +@@ -762,13 +770,11 @@ check_connection_interface_name (NMConnection *orig, + const char *orig_ifname, *cand_ifname; + NMSettingConnection *s_con_orig, *s_con_cand; + +- props = g_hash_table_lookup (settings, NM_SETTING_CONNECTION_SETTING_NAME); +- if ( !props +- || (g_hash_table_size (props) != 1) +- || !g_hash_table_lookup (props, NM_SETTING_CONNECTION_INTERFACE_NAME)) { +- /* We only handle 'interface-name' here. */ +- return FALSE; +- } ++ props = check_property_in_hash (settings, ++ NM_SETTING_CONNECTION_SETTING_NAME, ++ NM_SETTING_CONNECTION_INTERFACE_NAME); ++ if (!props) ++ return TRUE; + + /* If one of the interface name is NULL, we accept that connection */ + s_con_orig = nm_connection_get_setting_connection (orig); +@@ -776,9 +782,12 @@ check_connection_interface_name (NMConnection *orig, + orig_ifname = nm_setting_connection_get_interface_name (s_con_orig); + cand_ifname = nm_setting_connection_get_interface_name (s_con_cand); + +- if (!orig_ifname || !cand_ifname) ++ if (!orig_ifname || !cand_ifname) { ++ remove_from_hash (settings, props, ++ NM_SETTING_CONNECTION_SETTING_NAME, ++ NM_SETTING_CONNECTION_INTERFACE_NAME); + return TRUE; +- ++ } + return FALSE; + } + +@@ -790,19 +799,19 @@ check_possible_match (NMConnection *orig, + { + g_return_val_if_fail (settings != NULL, NULL); + +- if (check_ip6_method_link_local_auto (orig, candidate, settings)) +- return candidate; ++ if (!check_ip6_method (orig, candidate, settings)) ++ return NULL; + +- if (check_ip6_method_link_local_ignore (orig, candidate, settings)) +- return candidate; ++ if (!check_ip4_method (orig, candidate, settings, device_has_carrier)) ++ return NULL; + +- if (check_ip4_method_disabled_auto (orig, candidate, settings, device_has_carrier)) +- return candidate; ++ if (!check_connection_interface_name (orig, candidate, settings)) ++ return NULL; + +- if (check_connection_interface_name (orig, candidate, settings)) ++ if (g_hash_table_size (settings) == 0) + return candidate; +- +- return NULL; ++ else ++ return NULL; + } + + /** +-- +1.7.11.7 + + +From 1301995202308842c572b2f543f95b37142926d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 7 Apr 2014 15:25:09 +0200 +Subject: [PATCH 2/5] device: add s390 values to connection in + update_connection() (rh #1083196) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + src/devices/nm-device-ethernet.c | 110 +++++++++++++++++++++++++++------------ + 1 file changed, 78 insertions(+), 32 deletions(-) + +diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c +index e6f091d..920d255 100644 +--- a/src/devices/nm-device-ethernet.c ++++ b/src/devices/nm-device-ethernet.c +@@ -15,7 +15,7 @@ + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * +- * Copyright (C) 2005 - 2013 Red Hat, Inc. ++ * Copyright (C) 2005 - 2014 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +@@ -114,6 +114,8 @@ typedef struct { + char * subchan2; + char * subchan3; + char * subchannels; /* Composite used for checking unmanaged specs */ ++ char * s390_nettype; ++ GHashTable * s390_options; + + /* PPPoE */ + NMPPPManager *ppp_manager; +@@ -145,6 +147,25 @@ nm_ethernet_error_quark (void) + return quark; + } + ++static char * ++get_link_basename (const char *parent_path, const char *name, GError **error) ++{ ++ char buf[128]; ++ char *path; ++ char *result = NULL; ++ ++ path = g_strdup_printf ("%s/%s", parent_path, name); ++ ++ memset (buf, 0, sizeof (buf)); ++ errno = 0; ++ if (readlink (path, &buf[0], sizeof (buf) - 1) >= 0) ++ result = g_path_get_basename (buf); ++ else ++ g_set_error (error, 0, 1, "failed to read link '%s': %d", path, errno); ++ g_free (path); ++ return result; ++} ++ + static void + _update_s390_subchannels (NMDeviceEthernet *self) + { +@@ -192,34 +213,33 @@ _update_s390_subchannels (NMDeviceEthernet *self) + goto out; + } + +- /* FIXME: we probably care about ordering here to ensure that we map +- * cdev0 -> subchan1, cdev1 -> subchan2, etc. +- */ + while ((item = g_dir_read_name (dir))) { +- char buf[50]; +- char *cdev_path; +- +- if (strncmp (item, "cdev", 4)) +- continue; /* Not a subchannel link */ +- +- cdev_path = g_strdup_printf ("%s/%s", parent_path, item); +- +- memset (buf, 0, sizeof (buf)); +- errno = 0; +- if (readlink (cdev_path, &buf[0], sizeof (buf) - 1) >= 0) { +- if (!priv->subchan1) +- priv->subchan1 = g_path_get_basename (buf); +- else if (!priv->subchan2) +- priv->subchan2 = g_path_get_basename (buf); +- else if (!priv->subchan3) +- priv->subchan3 = g_path_get_basename (buf); +- } else { +- nm_log_warn (LOGD_DEVICE | LOGD_HW, +- "(%s): failed to read cdev link '%s': %d", +- iface, cdev_path, errno); ++ if (!strcmp (item, "cdev0")) { ++ priv->subchan1 = get_link_basename (parent_path, "cdev0", &error); ++ } else if (!strcmp (item, "cdev1")) { ++ priv->subchan2 = get_link_basename (parent_path, "cdev1", &error); ++ } else if (!strcmp (item, "cdev2")) { ++ priv->subchan3 = get_link_basename (parent_path, "cdev2", &error); ++ } else if (!strcmp (item, "driver")) { ++ priv->s390_nettype = get_link_basename (parent_path, "driver", &error); ++ } else if ( !strcmp (item, "layer2") ++ || !strcmp (item, "portname") ++ || !strcmp (item, "portno")) { ++ char *path, *value; ++ path = g_strdup_printf ("%s/%s", parent_path, item); ++ value = nm_platform_sysctl_get (path); ++ if (value && *value) ++ g_hash_table_insert (priv->s390_options, g_strdup (item), g_strdup (value)); ++ else ++ nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): error reading %s", iface, path); ++ g_free (path); ++ g_free (value); + } +- g_free (cdev_path); +- }; ++ if (error) { ++ nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): %s", iface, error->message); ++ g_clear_error (&error); ++ } ++ } + + g_dir_close (dir); + +@@ -250,8 +270,8 @@ out: + + static GObject* + constructor (GType type, +- guint n_construct_params, +- GObjectConstructParam *construct_params) ++ guint n_construct_params, ++ GObjectConstructParam *construct_params) + { + GObject *object; + NMDevice *self; +@@ -268,8 +288,8 @@ constructor (GType type, + || nm_platform_link_get_type (ifindex) == NM_LINK_TYPE_VETH); + + nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", +- nm_device_get_iface (NM_DEVICE (self)), +- nm_device_get_ifindex (NM_DEVICE (self))); ++ nm_device_get_iface (NM_DEVICE (self)), ++ nm_device_get_ifindex (NM_DEVICE (self))); + + /* s390 stuff */ + _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); +@@ -305,8 +325,10 @@ device_state_changed (NMDevice *device, + } + + static void +-nm_device_ethernet_init (NMDeviceEthernet * self) ++nm_device_ethernet_init (NMDeviceEthernet *self) + { ++ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); ++ priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + } + + NMDevice * +@@ -1543,6 +1565,8 @@ update_connection (NMDevice *device, NMConnection *connection) + static const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; + GByteArray *array; ++ GHashTableIter iter; ++ gpointer key, value; + + if (!s_wired) { + s_wired = (NMSettingWired *) nm_setting_wired_new (); +@@ -1571,6 +1595,26 @@ update_connection (NMDevice *device, NMConnection *connection) + } + + /* We don't set the MTU as we don't know whether it was set explicitly */ ++ ++ /* s390 */ ++ if (priv->subchannels) { ++ GPtrArray *subchan_arr = g_ptr_array_sized_new (3); ++ if (priv->subchan1) ++ g_ptr_array_add (subchan_arr, priv->subchan1); ++ if (priv->subchan2) ++ g_ptr_array_add (subchan_arr, priv->subchan2); ++ if (priv->subchan3) ++ g_ptr_array_add (subchan_arr, priv->subchan3); ++ g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, NULL); ++ g_ptr_array_free (subchan_arr, TRUE); ++ } ++ if (priv->s390_nettype) ++ g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL); ++ g_hash_table_iter_init (&iter, priv->s390_options); ++ while (g_hash_table_iter_next (&iter, &key, &value)) { ++ nm_setting_wired_add_s390_option (s_wired, (const char *) key, (const char *) value); ++ } ++ + } + + static void +@@ -1638,6 +1682,8 @@ dispose (GObject *object) + g_free (priv->subchan2); + g_free (priv->subchan3); + g_free (priv->subchannels); ++ g_free (priv->s390_nettype); ++ g_hash_table_destroy (priv->s390_options); + + if (priv->pppoe_wait_id) { + g_source_remove (priv->pppoe_wait_id); +-- +1.7.11.7 + + +From 7251e4ea22f0a281da87e0d1c28c3405bf75068a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Tue, 8 Apr 2014 10:49:16 +0200 +Subject: [PATCH 3/5] utils: allow matching connections with no MAC (missing + HWADDR) (rh #1083196) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + src/NetworkManagerUtils.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c +index e0a232e..52b7c43 100644 +--- a/src/NetworkManagerUtils.c ++++ b/src/NetworkManagerUtils.c +@@ -791,6 +791,36 @@ check_connection_interface_name (NMConnection *orig, + return FALSE; + } + ++static gboolean ++check_connection_mac_address (NMConnection *orig, ++ NMConnection *candidate, ++ GHashTable *settings) ++{ ++ GHashTable *props; ++ const GByteArray *orig_mac, *cand_mac; ++ NMSettingWired *s_wired_orig, *s_wired_cand; ++ ++ props = check_property_in_hash (settings, ++ NM_SETTING_WIRED_SETTING_NAME, ++ NM_SETTING_WIRED_MAC_ADDRESS); ++ if (!props) ++ return TRUE; ++ ++ /* If one of the MAC addresses is NULL, we accept that connection */ ++ s_wired_orig = nm_connection_get_setting_wired (orig); ++ s_wired_cand = nm_connection_get_setting_wired (candidate); ++ orig_mac = nm_setting_wired_get_mac_address (s_wired_orig); ++ cand_mac = nm_setting_wired_get_mac_address (s_wired_cand); ++ ++ if (!orig_mac || !cand_mac) { ++ remove_from_hash (settings, props, ++ NM_SETTING_WIRED_SETTING_NAME, ++ NM_SETTING_WIRED_MAC_ADDRESS); ++ return TRUE; ++ } ++ return FALSE; ++} ++ + static NMConnection * + check_possible_match (NMConnection *orig, + NMConnection *candidate, +@@ -808,6 +838,9 @@ check_possible_match (NMConnection *orig, + if (!check_connection_interface_name (orig, candidate, settings)) + return NULL; + ++ if (!check_connection_mac_address (orig, candidate, settings)) ++ return NULL; ++ + if (g_hash_table_size (settings) == 0) + return candidate; + else +-- +1.7.11.7 + + +From ff2b655691af48cf73d7780fdd662cd861c365c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Tue, 8 Apr 2014 10:39:31 +0200 +Subject: [PATCH 4/5] tests: improve tests for nm_utils_match_connection() + function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +nm_utils_match_connection() is the main function used to match connections +when assuming connections on startup. + +Signed-off-by: Jiří Klimeš +--- + src/tests/test-general.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 113 insertions(+) + +diff --git a/src/tests/test-general.c b/src/tests/test-general.c +index ecbda9a..207191f 100644 +--- a/src/tests/test-general.c ++++ b/src/tests/test-general.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "NetworkManagerUtils.h" + #include "nm-utils.h" +@@ -440,6 +441,116 @@ test_connection_match_interface_name (void) + g_object_unref (copy); + } + ++static void ++test_connection_match_wired (void) ++{ ++ NMConnection *orig, *copy, *matched; ++ GSList *connections = NULL; ++ NMSettingWired *s_wired; ++ GPtrArray *subchan_arr = g_ptr_array_sized_new (3); ++ GByteArray *mac; ++ ++ g_ptr_array_add (subchan_arr, "0.0.8000"); ++ g_ptr_array_add (subchan_arr, "0.0.8001"); ++ g_ptr_array_add (subchan_arr, "0.0.8002"); ++ ++ orig = _match_connection_new (); ++ copy = nm_connection_duplicate (orig); ++ connections = g_slist_append (connections, copy); ++ ++ mac = nm_utils_hwaddr_atoba ("52:54:00:ab:db:23", ARPHRD_ETHER); ++ s_wired = nm_connection_get_setting_wired (orig); ++ g_assert (s_wired); ++ g_object_set (G_OBJECT (s_wired), ++ NM_SETTING_WIRED_PORT, "tp", /* port is not compared */ ++ NM_SETTING_WIRED_MAC_ADDRESS, mac, /* we allow MAC address just in one connection */ ++ NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, ++ NM_SETTING_WIRED_S390_NETTYPE, "qeth", ++ NULL); ++ g_byte_array_free (mac, TRUE); ++ ++ s_wired = nm_connection_get_setting_wired (copy); ++ g_assert (s_wired); ++ g_object_set (G_OBJECT (s_wired), ++ NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, ++ NM_SETTING_WIRED_S390_NETTYPE, "qeth", ++ NULL); ++ ++ matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); ++ g_assert (matched == copy); ++ ++ g_slist_free (connections); ++ g_ptr_array_free (subchan_arr, TRUE); ++ g_object_unref (orig); ++ g_object_unref (copy); ++} ++ ++static void ++test_connection_no_match_ip4_addr (void) ++{ ++ NMConnection *orig, *copy, *matched; ++ GSList *connections = NULL; ++ NMSettingIP4Config *s_ip4; ++ NMSettingIP6Config *s_ip6; ++ NMIP4Address *nm_addr; ++ guint32 addr, gw; ++ ++ orig = _match_connection_new (); ++ copy = nm_connection_duplicate (orig); ++ connections = g_slist_append (connections, copy); ++ ++ /* Check that if we have two differences, ipv6.method (exception we allow) and ++ * ipv4.addresses (which is fatal), we don't match the connections. ++ */ ++ s_ip6 = nm_connection_get_setting_ip6_config (orig); ++ g_assert (s_ip6); ++ g_object_set (G_OBJECT (s_ip6), ++ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, ++ NULL); ++ ++ s_ip6 = nm_connection_get_setting_ip6_config (copy); ++ g_assert (s_ip6); ++ g_object_set (G_OBJECT (s_ip6), ++ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, ++ NULL); ++ ++ ++ s_ip4 = nm_connection_get_setting_ip4_config (orig); ++ g_assert (s_ip4); ++ g_object_set (G_OBJECT (s_ip4), ++ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, ++ NULL); ++ nm_addr = nm_ip4_address_new (); ++ inet_pton (AF_INET, "1.1.1.4", &addr); ++ inet_pton (AF_INET, "1.1.1.254", &gw); ++ nm_ip4_address_set_address (nm_addr, addr); ++ nm_ip4_address_set_prefix (nm_addr, 24); ++ nm_ip4_address_set_gateway (nm_addr, gw); ++ nm_setting_ip4_config_add_address (s_ip4, nm_addr); ++ nm_ip4_address_unref (nm_addr); ++ ++ s_ip4 = nm_connection_get_setting_ip4_config (copy); ++ g_assert (s_ip4); ++ g_object_set (G_OBJECT (s_ip4), ++ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, ++ NULL); ++ nm_addr = nm_ip4_address_new (); ++ inet_pton (AF_INET, "2.2.2.4", &addr); ++ inet_pton (AF_INET, "2.2.2.254", &gw); ++ nm_ip4_address_set_address (nm_addr, addr); ++ nm_ip4_address_set_prefix (nm_addr, 24); ++ nm_ip4_address_set_gateway (nm_addr, gw); ++ nm_setting_ip4_config_add_address (s_ip4, nm_addr); ++ nm_ip4_address_unref (nm_addr); ++ ++ matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); ++ g_assert (matched != copy); ++ ++ g_slist_free (connections); ++ g_object_unref (orig); ++ g_object_unref (copy); ++} ++ + /*******************************************/ + + int +@@ -457,6 +568,8 @@ main (int argc, char **argv) + g_test_add_func ("/general/connection-match/ip6-method-ignore", test_connection_match_ip6_method_ignore); + g_test_add_func ("/general/connection-match/ip4-method", test_connection_match_ip4_method); + g_test_add_func ("/general/connection-match/con-interface-name", test_connection_match_interface_name); ++ g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); ++ g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr); + + return g_test_run (); + } +-- +1.7.11.7 + + +From 59c0b7258c3bb7bc818b979eb2aeaf9bb9700e29 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 7 Apr 2014 15:34:10 +0200 +Subject: [PATCH 5/5] device-ethernet: add finalize() method +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + src/devices/nm-device-ethernet.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c +index 920d255..79e9086 100644 +--- a/src/devices/nm-device-ethernet.c ++++ b/src/devices/nm-device-ethernet.c +@@ -1677,14 +1677,6 @@ dispose (GObject *object) + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + +- g_clear_object (&priv->supplicant.mgr); +- g_free (priv->subchan1); +- g_free (priv->subchan2); +- g_free (priv->subchan3); +- g_free (priv->subchannels); +- g_free (priv->s390_nettype); +- g_hash_table_destroy (priv->s390_options); +- + if (priv->pppoe_wait_id) { + g_source_remove (priv->pppoe_wait_id); + priv->pppoe_wait_id = 0; +@@ -1697,6 +1689,23 @@ dispose (GObject *object) + } + + static void ++finalize (GObject *object) ++{ ++ NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); ++ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); ++ ++ g_clear_object (&priv->supplicant.mgr); ++ g_free (priv->subchan1); ++ g_free (priv->subchan2); ++ g_free (priv->subchan3); ++ g_free (priv->subchannels); ++ g_free (priv->s390_nettype); ++ g_hash_table_destroy (priv->s390_options); ++ ++ G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object); ++} ++ ++static void + get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) + { +@@ -1740,6 +1749,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) + /* virtual methods */ + object_class->constructor = constructor; + object_class->dispose = dispose; ++ object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + +-- +1.7.11.7 + +From 981e33b83b57377d04fa6caa50a4434c59fb9285 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Fri, 11 Apr 2014 12:46:53 +0200 +Subject: [PATCH] core: replace readlink() by glib equivalent in + NMDeviceEthernet +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Makes the function working for link destinations longer then 127 bytes and +fixes a potential bug that the result of readlink() was not zero +terminated for long paths. + +Probably this would be no problem, but better be save. + +Related: https://bugzilla.redhat.com/attachment.cgi?id=885371 + +Signed-off-by: Thomas Haller +Signed-off-by: Jiří Klimeš +--- + src/devices/nm-device-ethernet.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c +index 79e9086..e9937e4 100644 +--- a/src/devices/nm-device-ethernet.c ++++ b/src/devices/nm-device-ethernet.c +@@ -150,18 +150,15 @@ nm_ethernet_error_quark (void) + static char * + get_link_basename (const char *parent_path, const char *name, GError **error) + { +- char buf[128]; +- char *path; ++ char *link_dest, *path; + char *result = NULL; + + path = g_strdup_printf ("%s/%s", parent_path, name); +- +- memset (buf, 0, sizeof (buf)); +- errno = 0; +- if (readlink (path, &buf[0], sizeof (buf) - 1) >= 0) +- result = g_path_get_basename (buf); +- else +- g_set_error (error, 0, 1, "failed to read link '%s': %d", path, errno); ++ link_dest = g_file_read_link (path, error); ++ if (link_dest) { ++ result = g_path_get_basename (link_dest); ++ g_free (link_dest); ++ } + g_free (path); + return result; + } +-- +1.7.11.7 + diff --git a/SOURCES/rh1086237-dhcpv6-addr-lifetime.patch b/SOURCES/rh1086237-dhcpv6-addr-lifetime.patch new file mode 100644 index 0000000..1c357df --- /dev/null +++ b/SOURCES/rh1086237-dhcpv6-addr-lifetime.patch @@ -0,0 +1,46 @@ +From af9d166197ede942726117965729cf092308f5a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Wed, 28 May 2014 15:53:17 +0200 +Subject: [PATCH] dhcp: dhclient v6 stores address lifetimes in different + variables (rh #1086237) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It uses 'new_max_life' for valid lifetime and 'new_preferred_life' for +preferred lifetime. + +https://bugzilla.redhat.com/show_bug.cgi?id=1086237 + +Signed-off-by: Jiří Klimeš +--- + src/dhcp-manager/nm-dhcp-client.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c +index 6cec744..c8a9461 100644 +--- a/src/dhcp-manager/nm-dhcp-client.c ++++ b/src/dhcp-manager/nm-dhcp-client.c +@@ -1388,10 +1388,16 @@ ip6_options_to_config (NMDHCPClient *self) + + ip6_config = nm_ip6_config_new (); + +- str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time"); ++ str = g_hash_table_lookup (priv->options, "new_max_life"); + if (str) { +- address.lifetime = address.preferred = strtoul (str, NULL, 10); +- nm_log_info (LOGD_DHCP6, " lease time %d", address.lifetime); ++ address.lifetime = strtoul (str, NULL, 10); ++ nm_log_info (LOGD_DHCP6, " valid_lft %d", address.lifetime); ++ } ++ ++ str = g_hash_table_lookup (priv->options, "new_preferred_life"); ++ if (str) { ++ address.preferred = strtoul (str, NULL, 10); ++ nm_log_info (LOGD_DHCP6, " preferred_lft %d", address.preferred); + } + + str = g_hash_table_lookup (priv->options, "new_ip6_address"); +-- +1.7.11.7 + diff --git a/SOURCES/rh1086237-ipv6-route-matching.patch b/SOURCES/rh1086237-ipv6-route-matching.patch new file mode 100644 index 0000000..fdb55c3 --- /dev/null +++ b/SOURCES/rh1086237-ipv6-route-matching.patch @@ -0,0 +1,48 @@ +From 9a98bc74462c11e7906195d359644ca853377170 Mon Sep 17 00:00:00 2001 +From: Dan Winship +Date: Tue, 29 Apr 2014 11:06:53 -0400 +Subject: [PATCH] core: fix connection matching with IPv6 routes (rh #1086237) + +An IPv6 router may have sent us arbitrary routes, so don't consider +them when comparing two method=auto connections. + +(A better fix would be to look at the route lifetime, to see if it's +dynamic or static, but we don't currently have that information.) + +https://bugzilla.gnome.org/show_bug.cgi?id=729203 +--- + src/nm-ip6-config.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff -up NetworkManager-0.9.9.1/src/nm-ip6-config.c.ipv6 NetworkManager-0.9.9.1/src/nm-ip6-config.c +--- NetworkManager-0.9.9.1/src/nm-ip6-config.c.ipv6 2014-05-12 08:02:40.862188963 -0400 ++++ NetworkManager-0.9.9.1/src/nm-ip6-config.c 2014-05-12 08:04:36.251198172 -0400 +@@ -430,7 +430,7 @@ nm_ip6_config_update_setting (const NMIP + /* Routes */ + for (i = 0; i < nroutes; i++) { + const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); +- NMIP6Route *s_route = nm_ip6_route_new (); ++ NMIP6Route *s_route; + + /* Ignore link-local route. */ + if (IN6_IS_ADDR_LINKLOCAL (&route->network)) +@@ -440,6 +440,11 @@ nm_ip6_config_update_setting (const NMIP + if (!route->plen) + continue; + ++ /* Assume all routes on 'auto' connections came from the router. */ ++ if (!g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) ++ continue; ++ ++ s_route = nm_ip6_route_new (); + nm_ip6_route_set_dest (s_route, &route->network); + nm_ip6_route_set_prefix (s_route, route->plen); + if (!IN6_IS_ADDR_UNSPECIFIED (&route->network)) +@@ -447,6 +452,7 @@ nm_ip6_config_update_setting (const NMIP + nm_ip6_route_set_metric (s_route, route->metric); + + nm_setting_ip6_config_add_route (setting, s_route); ++ nm_ip6_route_unref (s_route); + } + + /* DNS */ diff --git a/SOURCES/rh1096063-NM-w-o-for-IPv4-and-IPv6.patch b/SOURCES/rh1096063-NM-w-o-for-IPv4-and-IPv6.patch new file mode 100644 index 0000000..ffbc772 --- /dev/null +++ b/SOURCES/rh1096063-NM-w-o-for-IPv4-and-IPv6.patch @@ -0,0 +1,505 @@ +From 116501dbccf7139f942c77e71c4afb5f6d1af6a8 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 28 Apr 2014 11:18:05 +0200 +Subject: [PATCH 1/2] core: add parameter to ignore error in add/remove pending + action + +Add a parameter to nm_device_add_pending_action() to silently +accept adding duplicate actions. + +Same for nm_device_remove_pending_action(), to silently ignore +removing non-pending actions. + +Signed-off-by: Thomas Haller +(cherry picked from commit a16faa3985042dadb34600cb0df2eefc61360340) +--- + src/devices/nm-device-olpc-mesh.c | 4 +- + src/devices/nm-device-wifi.c | 8 ++-- + src/devices/nm-device.c | 89 ++++++++++++++++++++++++++------------- + src/devices/nm-device.h | 4 +- + src/nm-active-connection.c | 8 ++-- + src/nm-policy.c | 4 +- + 6 files changed, 74 insertions(+), 43 deletions(-) + +diff --git a/src/devices/nm-device-olpc-mesh.c b/src/devices/nm-device-olpc-mesh.c +index b85956e..52ba79a 100644 +--- a/src/devices/nm-device-olpc-mesh.c ++++ b/src/devices/nm-device-olpc-mesh.c +@@ -627,7 +627,7 @@ check_companion_cb (gpointer user_data) + } + + done: +- nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion"); ++ nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE); + return FALSE; + } + +@@ -645,7 +645,7 @@ state_changed (NMDevice *device, NMDeviceState new_state, + * transition to DISCONNECTED otherwise wait for our companion. + */ + g_idle_add (check_companion_cb, self); +- nm_device_add_pending_action (device, "waiting for companion"); ++ nm_device_add_pending_action (device, "waiting for companion", TRUE); + break; + case NM_DEVICE_STATE_ACTIVATED: + break; +diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c +index d539877..4b231ca 100644 +--- a/src/devices/nm-device-wifi.c ++++ b/src/devices/nm-device-wifi.c +@@ -360,7 +360,7 @@ supplicant_interface_acquire (NMDeviceWifi *self) + } + + if (nm_supplicant_interface_get_state (priv->supplicant.iface) < NM_SUPPLICANT_INTERFACE_STATE_READY) +- nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant"); ++ nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", TRUE); + + g_signal_connect (priv->supplicant.iface, + NM_SUPPLICANT_INTERFACE_STATE, +@@ -1722,7 +1722,7 @@ request_wireless_scan (gpointer user_data) + /* success */ + backoff = TRUE; + priv->requested_scan = TRUE; +- nm_device_add_pending_action (NM_DEVICE (self), "scan"); ++ nm_device_add_pending_action (NM_DEVICE (self), "scan", TRUE); + } + + if (ssids) { +@@ -1823,7 +1823,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, + + if (priv->requested_scan) { + priv->requested_scan = FALSE; +- nm_device_remove_pending_action (NM_DEVICE (self), "scan"); ++ nm_device_remove_pending_action (NM_DEVICE (self), "scan", TRUE); + } + } + +@@ -2364,7 +2364,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, + request_wireless_scan (self); + + if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY) +- nm_device_remove_pending_action (device, "waiting for supplicant"); ++ nm_device_remove_pending_action (device, "waiting for supplicant", TRUE); + break; + case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED: + remove_supplicant_interface_error_handler (self); +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index f16c4d4..b6e7ef2 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -1123,7 +1123,7 @@ nm_device_set_carrier (NMDevice *device, gboolean carrier) + if (priv->carrier_wait_id) { + g_source_remove (priv->carrier_wait_id); + priv->carrier_wait_id = 0; +- nm_device_remove_pending_action (device, "carrier wait"); ++ nm_device_remove_pending_action (device, "carrier wait", TRUE); + } + } else if (state <= NM_DEVICE_STATE_DISCONNECTED) { + nm_log_info (LOGD_DEVICE, "(%s): link disconnected", iface); +@@ -5539,7 +5539,7 @@ carrier_wait_timeout (gpointer user_data) + NMDevice *self = NM_DEVICE (user_data); + + NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0; +- nm_device_remove_pending_action (self, "carrier wait"); ++ nm_device_remove_pending_action (self, "carrier wait", TRUE); + return G_SOURCE_REMOVE; + } + +@@ -5587,10 +5587,10 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) + if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { + if (priv->carrier_wait_id) { + g_source_remove (priv->carrier_wait_id); +- nm_device_remove_pending_action (self, "carrier wait"); ++ nm_device_remove_pending_action (self, "carrier wait", TRUE); + } + priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self); +- nm_device_add_pending_action (self, "carrier wait"); ++ nm_device_add_pending_action (self, "carrier wait", TRUE); + } + + /* Can only get HW address of some devices when they are up */ +@@ -6852,7 +6852,7 @@ queued_set_state (gpointer user_data) + nm_device_queued_state_clear (self); + + nm_device_state_changed (self, new_state, new_reason); +- nm_device_remove_pending_action (self, queued_state_to_string (new_state)); ++ nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE); + } else { + g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN); + g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE); +@@ -6876,7 +6876,7 @@ nm_device_queue_state (NMDevice *self, + + /* Add pending action for the new state before clearing the queued states, so + * that we don't accidently pop all pending states and reach 'startup complete' */ +- nm_device_add_pending_action (self, queued_state_to_string (state)); ++ nm_device_add_pending_action (self, queued_state_to_string (state), TRUE); + + /* We should only ever have one delayed state transition at a time */ + if (priv->queued_state.id) { +@@ -6917,7 +6917,7 @@ nm_device_queued_state_clear (NMDevice *self) + nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued state transition (id %d)", + nm_device_get_iface (self), priv->queued_state.id); + g_source_remove (priv->queued_state.id); +- nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state)); ++ nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); + } + memset (&priv->queued_state, 0, sizeof (priv->queued_state)); + } +@@ -7651,31 +7651,46 @@ nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, + * nm_device_add_pending_action(): + * @device: the #NMDevice to add the pending action to + * @action: a static string that identifies the action ++ * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending. ++ * Otherwise, ignore duplicate scheduling of the same action silently. + * + * Adds a pending action to the device. ++ * ++ * Returns: %TRUE if the action was added (and not already added before). %FALSE ++ * if the same action is already scheduled. In the latter case, the action was not scheduled ++ * a second time. + */ +-void +-nm_device_add_pending_action (NMDevice *device, const char *action) ++gboolean ++nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GSList *iter; +- guint count; ++ guint count = 0; + +- g_return_if_fail (action); ++ g_return_val_if_fail (action, FALSE); + +- /* Shouldn't ever add the same pending action twice */ ++ /* Check if the action is already pending. Cannot add duplicate actions */ + for (iter = priv->pending_actions; iter; iter = iter->next) { + if (!strcmp (action, iter->data)) { +- nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already added", +- nm_device_get_iface (device), +- g_slist_length (priv->pending_actions), +- action); +- g_return_if_reached (); ++ if (assert_not_yet_pending) { ++ nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending", ++ nm_device_get_iface (device), ++ count + g_slist_length (iter), ++ action); ++ g_return_val_if_reached (FALSE); ++ } else { ++ nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending (expected)", ++ nm_device_get_iface (device), ++ count + g_slist_length (iter), ++ action); ++ } ++ return FALSE; + } ++ count++; + } + + priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action)); +- count = g_slist_length (priv->pending_actions); ++ count++; + + nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s'", + nm_device_get_iface (device), +@@ -7684,44 +7699,60 @@ nm_device_add_pending_action (NMDevice *device, const char *action) + + if (count == 1) + g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); ++ ++ return TRUE; + } + + /** + * nm_device_remove_pending_action(): + * @device: the #NMDevice to remove the pending action from + * @action: a static string that identifies the action ++ * @assert_is_pending: if %TRUE, assert that the @action is pending. ++ * If %FALSE, don't do anything if the current action is not pending and ++ * return %FALSE. + * + * Removes a pending action previously added by nm_device_add_pending_action(). ++ * ++ * Returns: whether the @action was pending and is now removed. + */ +-void +-nm_device_remove_pending_action (NMDevice *device, const char *action) ++gboolean ++nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GSList *iter; ++ guint count = 0; + +- g_return_if_fail (action); ++ g_return_val_if_fail (action, FALSE); + +- /* Shouldn't ever add the same pending action twice */ + for (iter = priv->pending_actions; iter; iter = iter->next) { + if (!strcmp (action, iter->data)) { + g_free (iter->data); + priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); + nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s'", + nm_device_get_iface (device), +- g_slist_length (priv->pending_actions), ++ count + g_slist_length (iter), + action); + + if (priv->pending_actions == NULL) + g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); +- return; ++ return TRUE; + } ++ count++; + } + +- nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' never added", +- nm_device_get_iface (device), +- g_slist_length (priv->pending_actions), +- action); +- g_return_if_reached (); ++ if (assert_is_pending) { ++ nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending", ++ nm_device_get_iface (device), ++ count, ++ action); ++ g_return_val_if_reached (FALSE); ++ } else { ++ nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending (expected)", ++ nm_device_get_iface (device), ++ count, ++ action); ++ } ++ return FALSE; + } + + gboolean +diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h +index 47d7856..935a448 100644 +--- a/src/devices/nm-device.h ++++ b/src/devices/nm-device.h +@@ -328,8 +328,8 @@ void nm_device_queue_activation (NMDevice *device, NMActRequest *req); + + gboolean nm_device_supports_vlans (NMDevice *device); + +-void nm_device_add_pending_action (NMDevice *device, const char *action); +-void nm_device_remove_pending_action (NMDevice *device, const char *action); ++gboolean nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending); ++gboolean nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending); + gboolean nm_device_has_pending_action (NMDevice *device); + + GPtrArray *nm_device_get_available_connections (NMDevice *device, +diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c +index 43f8189..172aa61 100644 +--- a/src/nm-active-connection.c ++++ b/src/nm-active-connection.c +@@ -152,7 +152,7 @@ nm_active_connection_set_state (NMActiveConnection *self, + && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED && + priv->pending_activation_id) + { +- nm_device_remove_pending_action (priv->device, priv->pending_activation_id); ++ nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE); + g_clear_pointer (&priv->pending_activation_id, g_free); + } + } +@@ -399,7 +399,7 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device) + + if (!priv->assumed) { + priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self); +- nm_device_add_pending_action (device, priv->pending_activation_id); ++ nm_device_add_pending_action (device, priv->pending_activation_id, TRUE); + } + } + return TRUE; +@@ -540,7 +540,7 @@ nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed) + priv->assumed = assumed; + + if (priv->pending_activation_id) { +- nm_device_remove_pending_action (priv->device, priv->pending_activation_id); ++ nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE); + g_clear_pointer (&priv->pending_activation_id, g_free); + } + } +@@ -795,7 +795,7 @@ _device_cleanup (NMActiveConnection *self) + } + + if (priv->pending_activation_id) { +- nm_device_remove_pending_action (priv->device, priv->pending_activation_id); ++ nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE); + g_clear_pointer (&priv->pending_activation_id, g_free); + } + +diff --git a/src/nm-policy.c b/src/nm-policy.c +index f569b75..b412427 100644 +--- a/src/nm-policy.c ++++ b/src/nm-policy.c +@@ -941,7 +941,7 @@ activate_data_free (ActivateData *data) + { + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (data->policy); + +- nm_device_remove_pending_action (data->device, "autoactivate"); ++ nm_device_remove_pending_action (data->device, "autoactivate", TRUE); + priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data); + + if (data->autoactivate_id) +@@ -1223,7 +1223,7 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device) + return; + } + +- nm_device_add_pending_action (device, "autoactivate"); ++ nm_device_add_pending_action (device, "autoactivate", TRUE); + + data = g_malloc0 (sizeof (ActivateData)); + data->policy = policy; +-- +1.9.0 + + +From e20f6c63b0a5f0dfb2851d6f5a098f8bb1f5a1be Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 14 Apr 2014 17:57:56 +0200 +Subject: [PATCH 2/2] core: wait with "startup complete" for both IPv4 and IPv6 + dynamic configuration + +In case of DHCP4, DHCP6 and/or SLAAC, delay "startup complete" until +both IPv4 and IPv6 are ready. This especially has an effect on +nm-online/NetworkManager-wait-online.service, which blocks until +configuration of both IPv4 and IPv6 is ready. + +We queue a pending_action when automatic configuration starts and +remove it again, when we receive an address. Before, "startup complete" +was reached when either one of the two IP protocols was configured. + +https://bugzilla.redhat.com/show_bug.cgi?id=1086906 + +Signed-off-by: Thomas Haller +(cherry picked from commit 516d66210fbcc9897f60dc9145a477e91ff8bad5) +--- + man/nm-online.1.in | 7 ++++++- + src/devices/nm-device.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/man/nm-online.1.in b/man/nm-online.1.in +index 941f006..86ed974 100644 +--- a/man/nm-online.1.in ++++ b/man/nm-online.1.in +@@ -35,7 +35,12 @@ is a utility to find out whether we are online. It is done by asking + NetworkManager about its status. When run, \fInm\-online\fP waits until + NetworkManager reports an active connection, or specified timeout expires. On + exit, the returned status code should be checked (see the return codes bellow). +- ++.P ++By default NetworkManager waits for IPv4 dynamic addressing to complete but does ++not wait for the "auto" IPv6 dynamic addressing. To wait for IPv6 addressing to ++complete, either (1) change the network connection's IPv6 "may-fail" setting to "no", ++and/or (2) change the IPv6 addressing method to "manual" or "dhcp", to indicate that ++IPv6 connectivity is expected. + .SH OPTIONS + .TP + .B \-t, \-\-timeout +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index b6e7ef2..8399cf6 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -156,6 +156,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMDevice, nm_device, G_TYPE_OBJECT, + + #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) + ++#define PENDING_ACTION_DHCP4 "dhcp4" ++#define PENDING_ACTION_DHCP6 "dhcp6" ++#define PENDING_ACTION_AUTOCONF6 "autoconf6" ++ + typedef enum { + IP_NONE = 0, + IP_WAIT, +@@ -2820,6 +2824,8 @@ dhcp4_start (NMDevice *self, + G_CALLBACK (dhcp4_timeout), + self); + ++ nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE); ++ + /* DHCP devices will be notified by the DHCP manager when stuff happens */ + return NM_ACT_STAGE_RETURN_POSTPONE; + } +@@ -3202,6 +3208,7 @@ dhcp6_start (NMDevice *self, + guint32 dhcp_opt, + NMDeviceStateReason *reason) + { ++ NMSettingIP6Config *s_ip6; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + guint8 *anycast = NULL; +@@ -3254,6 +3261,11 @@ dhcp6_start (NMDevice *self, + G_CALLBACK (dhcp6_timeout), + self); + ++ s_ip6 = nm_connection_get_setting_ip6_config (connection); ++ if (!nm_setting_ip6_config_get_may_fail (s_ip6) || ++ !strcmp (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) ++ nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); ++ + /* DHCP devices will be notified by the DHCP manager when stuff happens */ + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else { +@@ -3620,6 +3632,9 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) + priv->rdisc_use_tempaddr = use_tempaddr; + print_support_extended_ifa_flags (use_tempaddr); + ++ if (!nm_setting_ip6_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) ++ nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE); ++ + /* ensure link local is ready... */ + ret = linklocal6_start (self); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) +@@ -3663,6 +3678,8 @@ addrconf6_cleanup (NMDevice *self) + priv->rdisc_config_changed_sigid = 0; + } + ++ nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); ++ + g_clear_object (&priv->ac_ip6_config); + g_clear_object (&priv->rdisc); + } +@@ -4509,6 +4526,9 @@ nm_device_activate_ip4_config_commit (gpointer user_data) + + /* Enter the IP_CHECK state if this is the first method to complete */ + priv->ip4_state = IP_DONE; ++ ++ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); ++ + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); + +@@ -4598,6 +4618,10 @@ nm_device_activate_ip6_config_commit (gpointer user_data) + + /* Enter the IP_CHECK state if this is the first method to complete */ + priv->ip6_state = IP_DONE; ++ ++ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); ++ nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); ++ + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); + } else { +@@ -4683,6 +4707,8 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) + priv->dhcp4_timeout_sigid = 0; + } + ++ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); ++ + if (stop) + nm_dhcp_client_stop (priv->dhcp4_client, release); + +@@ -4720,6 +4746,8 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) + priv->dhcp6_timeout_sigid = 0; + } + ++ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); ++ + if (stop) + nm_dhcp_client_stop (priv->dhcp6_client, release); + +-- +1.9.0 + diff --git a/SOURCES/rh1100750-cli-vpn-types.patch b/SOURCES/rh1100750-cli-vpn-types.patch new file mode 100644 index 0000000..2819cd3 --- /dev/null +++ b/SOURCES/rh1100750-cli-vpn-types.patch @@ -0,0 +1,149 @@ +From 649e4be103589c5a137a582751a9ec84b12885e0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 26 May 2014 14:51:24 +0200 +Subject: [PATCH 1/2] cli: extract username and gateway for some more VPN + types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + cli/src/connections.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/cli/src/connections.c b/cli/src/connections.c +index 267d17c..295ca61 100644 +--- a/cli/src/connections.c ++++ b/cli/src/connections.c +@@ -939,6 +939,9 @@ find_vpn_gateway_key (const char *vpn_type) + if (g_strcmp0 (vpn_type, "pptp") == 0) return "gateway"; + if (g_strcmp0 (vpn_type, "openconnect") == 0) return "gateway"; + if (g_strcmp0 (vpn_type, "openswan") == 0) return "right"; ++ if (g_strcmp0 (vpn_type, "libreswan") == 0) return "right"; ++ if (g_strcmp0 (vpn_type, "ssh") == 0) return "remote"; ++ if (g_strcmp0 (vpn_type, "l2tp") == 0) return "gateway"; + return ""; + } + +@@ -950,6 +953,8 @@ find_vpn_username_key (const char *vpn_type) + if (g_strcmp0 (vpn_type, "pptp") == 0) return "user"; + if (g_strcmp0 (vpn_type, "openconnect") == 0) return "username"; + if (g_strcmp0 (vpn_type, "openswan") == 0) return "leftxauthusername"; ++ if (g_strcmp0 (vpn_type, "libreswan") == 0) return "leftxauthusername"; ++ if (g_strcmp0 (vpn_type, "l2tp") == 0) return "user"; + return ""; + } + +-- +1.7.11.7 + + +From d7216505bbfe0de976d477609c06528432c380d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 26 May 2014 15:19:47 +0200 +Subject: [PATCH 2/2] cli: do not restrict VPN type of created connections (rh + #1100750) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There may be third-party VPN plugins nmcli is not aware of. +We still print a warning if nmcli doesn't know the type. It helps to catch up +typos. + +https://bugzilla.redhat.com/show_bug.cgi?id=1100750 + +Signed-off-by: Jiří Klimeš +--- + cli/completion/nmcli | 2 +- + cli/src/connections.c | 20 +++++++++----------- + man/nmcli.1.in | 2 +- + 3 files changed, 11 insertions(+), 13 deletions(-) + +diff --git a/cli/completion/nmcli b/cli/completion/nmcli +index bbfee3a..0a185a1 100644 +--- a/cli/completion/nmcli ++++ b/cli/completion/nmcli +@@ -419,7 +419,7 @@ _nmcli_compl_ARGS() + ;; + vpn-type) + if [[ "${#words[@]}" -eq 2 ]]; then +- _nmcli_list "vpnc openvpn pptp openconnect openswan" ++ _nmcli_list "vpnc openvpn pptp openconnect openswan libreswan ssh l2tp iodine" + return 0 + fi + ;; +diff --git a/cli/src/connections.c b/cli/src/connections.c +index 295ca61..3580c79 100644 +--- a/cli/src/connections.c ++++ b/cli/src/connections.c +@@ -400,7 +400,7 @@ usage_connection_add (void) + " [priority <0-63>]\n" + " [path-cost <1-65535>]\n" + " [hairpin yes|no]\n\n" +- " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan\n" ++ " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|ssh|l2tp|iodine|...\n" + " [user ]\n\n" + " olpc-mesh: ssid \n" + " [channel <1-13>]\n" +@@ -4758,14 +4758,14 @@ cleanup_bridge_slave: + } else if (!strcmp (con_type, NM_SETTING_VPN_SETTING_NAME)) { + /* Build up the settings required for 'vpn' */ + gboolean success = FALSE; +- const char *valid_vpns[] = { "openvpn", "vpnc", "pptp", "openconnect", "openswan", NULL }; ++ const char *known_vpns[] = { "openvpn", "vpnc", "pptp", "openconnect", "openswan", "libreswan", ++ "ssh", "l2tp", "iodine", NULL }; + const char *vpn_type = NULL; + char *vpn_type_ask = NULL; + const char *user_c = NULL; + char *user = NULL; + const char *st; + char *service_type = NULL; +- GError *tmp_err = NULL; + nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask}, + {"user", TRUE, &user_c, FALSE}, + {NULL} }; +@@ -4781,19 +4781,17 @@ cleanup_bridge_slave: + goto cleanup_vpn; + } + ++ if (!(st = nmc_string_is_valid (vpn_type, known_vpns, NULL))) { ++ printf (_("Warning: 'vpn-type': %s not known.\n"), vpn_type); ++ st = vpn_type; ++ } ++ service_type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, st); ++ + /* Also ask for all optional arguments if '--ask' is specified. */ + user = user_c ? g_strdup (user_c) : NULL; + if (ask) + do_questionnaire_vpn (&user); + +- if (!(st = nmc_string_is_valid (vpn_type, valid_vpns, &tmp_err))) { +- g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, +- _("Error: 'vpn-type': %s."), tmp_err->message); +- g_clear_error (&tmp_err); +- goto cleanup_vpn; +- } +- service_type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, st); +- + /* Add 'vpn' setting */ + s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); +diff --git a/man/nmcli.1.in b/man/nmcli.1.in +index 6eb6f1f..1d91e89 100644 +--- a/man/nmcli.1.in ++++ b/man/nmcli.1.in +@@ -573,7 +573,7 @@ to be sent back out through the slave the frame was received on (default: yes) + .RS + .TP + .B vpn: +-.IP "\fIvpn-type vpnc|openvpn|pptp|openconnect|openswan\fP" 42 ++.IP "\fIvpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|ssh|l2tp|iodine|...\fP" 42 + \(en VPN type + .IP "\fI[user ]\fP" 42 + \(en VPN username +-- +1.7.11.7 + diff --git a/SOURCES/rh1103702-tui-ipv6-addr-crash-fix.patch b/SOURCES/rh1103702-tui-ipv6-addr-crash-fix.patch new file mode 100644 index 0000000..c1b0650 --- /dev/null +++ b/SOURCES/rh1103702-tui-ipv6-addr-crash-fix.patch @@ -0,0 +1,69 @@ +From 5378d7929eac07d55d5aa128ed21d6c03b14acf2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 2 Jun 2014 14:32:18 +0200 +Subject: [PATCH 1/2] tui: fix a crash when editing an IPv6 address (rh + #1103702) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1103702 + +Signed-off-by: Jiří Klimeš +--- + tui/nm-editor-bindings.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tui/nm-editor-bindings.c b/tui/nm-editor-bindings.c +index 44c9ec9..58346cd 100644 +--- a/tui/nm-editor-bindings.c ++++ b/tui/nm-editor-bindings.c +@@ -671,7 +671,7 @@ ip6_addresses_with_prefix_from_strv (GBinding *binding, + NULL); + + for (i = 0; strings[i]; i++) { +- if (i > addrs->len) { ++ if (i >= addrs->len) { + addr = g_value_array_new (3); + + g_value_init (&val, DBUS_TYPE_G_UCHAR_ARRAY); +-- +1.7.11.7 + + +From d7b8aeea335498771bc66faae0cbd938b02ce84a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Mon, 2 Jun 2014 14:36:16 +0200 +Subject: [PATCH 2/2] tui: use 128 as the default prefix for IPv6 addresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + tui/nm-editor-bindings.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/tui/nm-editor-bindings.c b/tui/nm-editor-bindings.c +index 58346cd..7f76f14 100644 +--- a/tui/nm-editor-bindings.c ++++ b/tui/nm-editor-bindings.c +@@ -104,8 +104,12 @@ ip_string_parse (const char *text, + || (family == AF_INET && *prefix > 32) + || (family == AF_INET6 && *prefix > 128)) + valid = FALSE; +- } else if (prefix) +- *prefix = 32; ++ } else if (prefix) { ++ if (family == AF_INET) ++ *prefix = 32; ++ else ++ *prefix = 128; ++ } + + return valid; + } +-- +1.7.11.7 + diff --git a/SOURCES/rh1103702-tui-ipv6-route-crash-fix.patch b/SOURCES/rh1103702-tui-ipv6-route-crash-fix.patch new file mode 100644 index 0000000..c315f2e --- /dev/null +++ b/SOURCES/rh1103702-tui-ipv6-route-crash-fix.patch @@ -0,0 +1,256 @@ +From 92898e84d6aebc3ab11799476d7ab8c0d1627949 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= +Date: Tue, 3 Jun 2014 12:38:07 +0200 +Subject: [PATCH 1/3] tui: fix a crash when editing IPv6 routes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +Signed-off-by: Jiří Klimeš +--- + tui/nm-editor-bindings.c | 14 +++++++------- + tui/nmt-route-entry.c | 2 +- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tui/nm-editor-bindings.c b/tui/nm-editor-bindings.c +index 7f76f14..5be1358 100644 +--- a/tui/nm-editor-bindings.c ++++ b/tui/nm-editor-bindings.c +@@ -772,7 +772,7 @@ ip6_addresses_to_strv (GBinding *binding, + for (i = 0; i < addrs->len; i++) { + addrbytes = addrs->pdata[i]; + if (IP6_ADDRESS_SET (addrbytes)) +- inet_ntop (AF_INET, addrbytes->data, buf, sizeof (buf)); ++ inet_ntop (AF_INET6, addrbytes->data, buf, sizeof (buf)); + else + buf[0] = '\0'; + strings[i] = g_strdup (buf); +@@ -1002,7 +1002,7 @@ ip6_route_transform_to_next_hop_string (GBinding *binding, + addrbytes = &in6addr_any; + + if (IN6_ADDR_SET (addrbytes)) +- inet_ntop (AF_INET, &addrbytes, buf, sizeof (buf)); ++ inet_ntop (AF_INET6, addrbytes, buf, sizeof (buf)); + else + buf[0] = '\0'; + g_value_set_string (target_value, buf); +@@ -1035,7 +1035,7 @@ ip6_route_transform_from_dest_string (GBinding *binding, + { + NMIP6Route *route; + const char *text; +- const struct in6_addr *addrbytes; ++ struct in6_addr addrbytes; + guint32 prefix; + + text = g_value_get_string (source_value); +@@ -1047,7 +1047,7 @@ ip6_route_transform_from_dest_string (GBinding *binding, + g_binding_get_source_property (binding), &route, + NULL); + +- nm_ip6_route_set_dest (route, addrbytes); ++ nm_ip6_route_set_dest (route, &addrbytes); + nm_ip6_route_set_prefix (route, prefix); + + g_value_take_boxed (target_value, route); +@@ -1062,21 +1062,21 @@ ip6_route_transform_from_next_hop_string (GBinding *binding, + { + NMIP6Route *route; + const char *text; +- const struct in6_addr *addrbytes; ++ struct in6_addr addrbytes; + + text = g_value_get_string (source_value); + if (*text) { + if (!ip_string_parse (text, AF_INET6, &addrbytes, NULL)) + return FALSE; + } else +- addrbytes = 0; ++ addrbytes = in6addr_any; + + /* Fetch the original property value */ + g_object_get (g_binding_get_source (binding), + g_binding_get_source_property (binding), &route, + NULL); + +- nm_ip6_route_set_next_hop (route, addrbytes); ++ nm_ip6_route_set_next_hop (route, &addrbytes); + + g_value_take_boxed (target_value, route); + return TRUE; +diff --git a/tui/nmt-route-entry.c b/tui/nmt-route-entry.c +index db8c254..1b20ca6 100644 +--- a/tui/nmt-route-entry.c ++++ b/tui/nmt-route-entry.c +@@ -206,7 +206,7 @@ nmt_route_entry_set_property (GObject *object, + priv->ip4_route = g_value_dup_boxed (value); + break; + case PROP_IP6_ROUTE: +- g_return_if_fail (priv->family == AF_INET); ++ g_return_if_fail (priv->family == AF_INET6); + if (priv->ip6_route) + nm_ip6_route_unref (priv->ip6_route); + priv->ip6_route = g_value_dup_boxed (value); +-- +1.7.11.7 + + +From 5ee85fe46e86fdc9e063c22700697802435503a6 Mon Sep 17 00:00:00 2001 +From: Dan Winship +Date: Tue, 3 Jun 2014 09:13:43 -0400 +Subject: [PATCH 2/3] tui: fix setting Clone MAC Address properties +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +NmtMacEntry wasn't notifying its mac-address property when it changed, +so the change never got saved to the NMSetting. + +https://bugzilla.gnome.org/show_bug.cgi?id=731160 + +Signed-off-by: Jiří Klimeš +--- + tui/nmt-mac-entry.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/tui/nmt-mac-entry.c b/tui/nmt-mac-entry.c +index d76c097..b065640 100644 +--- a/tui/nmt-mac-entry.c ++++ b/tui/nmt-mac-entry.c +@@ -28,6 +28,8 @@ + + #include "config.h" + ++#include ++ + #include + #include + +@@ -129,6 +131,17 @@ nmt_mac_entry_init (NmtMacEntry *entry) + } + + static void ++nmt_mac_entry_notify (GObject *object, ++ GParamSpec *pspec) ++{ ++ if (G_OBJECT_CLASS (nmt_mac_entry_parent_class)->notify) ++ G_OBJECT_CLASS (nmt_mac_entry_parent_class)->notify (object, pspec); ++ ++ if (pspec->owner_type == NMT_TYPE_NEWT_ENTRY && !strcmp (pspec->name, "text")) ++ g_object_notify (object, "mac-address"); ++} ++ ++static void + nmt_mac_entry_set_property (GObject *object, + guint prop_id, + const GValue *value, +@@ -189,6 +202,7 @@ nmt_mac_entry_class_init (NmtMacEntryClass *entry_class) + g_type_class_add_private (entry_class, sizeof (NmtMacEntryPrivate)); + + /* virtual methods */ ++ object_class->notify = nmt_mac_entry_notify; + object_class->set_property = nmt_mac_entry_set_property; + object_class->get_property = nmt_mac_entry_get_property; + +-- +1.7.11.7 + + +From d57795d474aaae7865d4d052605d5ddec65c429d Mon Sep 17 00:00:00 2001 +From: Dan Winship +Date: Tue, 3 Jun 2014 09:36:17 -0400 +Subject: [PATCH 3/3] tui: fix NmtMacEntry validation/display +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +NmtMacEntry would allow you to input 1 character more than it should +have. Fix that. + +Also, the code to insert ":"s automatically was bumping against some +weirdness in NmtNewtEntry that made it so that the ":" didn't get +displayed until you typed one more character after the one where it +got inserted. Hack around that by manually requesting a redraw. + +https://bugzilla.gnome.org/show_bug.cgi?id=731160 + +Signed-off-by: Jiří Klimeš +--- + tui/nmt-mac-entry.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/tui/nmt-mac-entry.c b/tui/nmt-mac-entry.c +index b065640..5e1c417 100644 +--- a/tui/nmt-mac-entry.c ++++ b/tui/nmt-mac-entry.c +@@ -82,7 +82,7 @@ mac_filter (NmtNewtEntry *entry, + { + NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry); + +- if (position > priv->mac_str_length) ++ if (position >= priv->mac_str_length) + return FALSE; + + return g_ascii_isxdigit (ch) || ch == ':'; +@@ -116,8 +116,13 @@ mac_validator (NmtNewtEntry *entry, + if (g_ascii_isxdigit (p[0]) && !p[1]) { + char *fixed = g_strdup_printf ("%.*s:%c", (int)(p - text), text, *p); + +- g_object_set (G_OBJECT (entry), "text", fixed, NULL); +- return TRUE; ++ nmt_newt_entry_set_text (entry, fixed); ++ g_free (fixed); ++ ++ /* FIXME: NmtNewtEntry doesn't correctly deal with us calling set_text() ++ * from inside the validator. ++ */ ++ nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (entry)); + } + + return FALSE; +-- +1.7.11.7 + +From 7f5b2f81b0b4bf86a0086d4004461e4d1bc95950 Mon Sep 17 00:00:00 2001 +From: Dan Winship +Date: Fri, 25 Apr 2014 11:01:21 -0400 +Subject: [PATCH] tui: fix route editing (rh #1090422) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +NmtRouteTable's ip4-routes and ip6-routes properties have the +D-Bus-based route list types (like the corresponding NMSetting +properties) so we have to convert our GSList-of-NMIP[46]Route data +into those types when updating the property. + +https://bugzilla.gnome.org/show_bug.cgi?id=728958 + +Signed-off-by: Jiří Klimeš +--- + tui/nmt-route-table.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/tui/nmt-route-table.c b/tui/nmt-route-table.c +index 75b2b67..d6173a0 100644 +--- a/tui/nmt-route-table.c ++++ b/tui/nmt-route-table.c +@@ -119,7 +119,14 @@ route_list_transform_from_route (GBinding *binding, + nm_ip6_route_unref (nth->data); + } + nth->data = g_value_dup_boxed (source_value); +- g_value_take_boxed (target_value, routes); ++ ++ if (priv->family == AF_INET) { ++ nm_utils_ip4_routes_to_gvalue (routes, target_value); ++ g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref); ++ } else if (priv->family == AF_INET6) { ++ nm_utils_ip6_routes_to_gvalue (routes, target_value); ++ g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref); ++ } + + return TRUE; + } +-- +1.7.11.7 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 87fa771..d222a3c 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -28,7 +28,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: %{realversion} -Release: 13%{snapshot}%{?git_sha}%{?dist} +Release: 22%{snapshot}%{?git_sha}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -47,6 +47,16 @@ Patch7: rh1083624-master-ignore-carrier.patch Patch8: rh1084554-balance-queued-state-lock.patch Patch9: rh1083153-ignore-cloned-routes.patch Patch10: rh1091296-dispatch-lease-change.patch +Patch11: rh1086237-ipv6-route-matching.patch +Patch12: rh1096063-NM-w-o-for-IPv4-and-IPv6.patch +Patch13: rh1100750-cli-vpn-types.patch +Patch14: rh1083196-match-connections-and-s390.patch +Patch15: rh1086237-dhcpv6-addr-lifetime.patch +Patch16: rh1067712-connection-order-fix.patch +Patch17: rh1083196-ipv6-method-ignore-auto.patch +Patch18: rh1103702-tui-ipv6-addr-crash-fix.patch +Patch19: rh1103702-tui-ipv6-route-crash-fix.patch +Patch20: 0020-rh1103782-firewall-zone-conflict.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -206,6 +216,16 @@ by nm-connection-editor and nm-applet in a non-graphical environment. %patch8 -p1 -b .rh1084554-balance-queued-state-lock %patch9 -p1 -b .rh1083153-ignore-cloned-routes %patch10 -p1 -b .rh1091296-dispatch-lease-change +%patch11 -p1 -b .rh1086237-ipv6-route-matching +%patch12 -p1 -b .0012.rh1096063-NM-w-o-for-IPv4-and-IPv6.orig +%patch13 -p1 -b .rh1100750-cli-vpn-types +%patch14 -p1 -b .rh1083196-match-connections-and-s390 +%patch15 -p1 -b .rh1086237-dhcpv6-addr-lifetime +%patch16 -p1 -b .rh1067712-connection-order-fix +%patch17 -p1 -b .rh1083196-ipv6-method-ignore-auto +%patch18 -p1 -b .rh1103702-tui-ipv6-addr-crash-fix +%patch19 -p1 -b .rh1103702-tui-ipv6-route-crash-fix +%patch20 -p1 -b .0020.rh1103782-firewall-zone-conflict.orig %build @@ -426,6 +446,36 @@ fi %endif %changelog +* Wed Jun 4 2014 Thomas Haller - 1:0.9.9.1-22.git20140326 +- core: fix ZONE_CONFLICT error when setting firewall zone (rh #1103782) + +* Tue Jun 3 2014 Jiří Klimeš - 1:0.9.9.1-21.git20140326 +- tui: fix a crash when editing IPv6 routes (rh #1103702) +- tui: fix setting Cloned MAC address + +* Mon Jun 2 2014 Jiří Klimeš - 1:0.9.9.1-20.git20140326 +- tui: fix a crash when editing IPv6 addresses (rh #1103702) + +* Fri May 30 2014 Jiří Klimeš - 1:0.9.9.1-19.git20140326 +- core: allow matching IPv6 'auto' connection to 'ignore' profile (rh #1083196) + +* Thu May 29 2014 Jiří Klimeš - 1:0.9.9.1-18.git20140326 +- core: sort connections in descending timestamp order on take-over (rh #1067712) + +* Thu May 29 2014 Jiří Klimeš - 1:0.9.9.1-17.git20140326 +- core: fix connection matching generally and for s390 as well (rh #1083196) +- dhcp: fix DHCPv6 address lifetime handling (rh #1086237) + +* Wed May 28 2014 Jiří Klimeš - 1:0.9.9.1-16.git20140326 +- cli: allow arbitrary VPN types when creating connections (rh #1100750) + +* Thu May 22 2014 Dan Williams - 1:0.9.9.1-15.git20140326 +- Rebuild for Z-stream update + +* Mon May 12 2014 Dan Winship - 1:0.9.9.1-14.git20140326 +- core: fix connection matching with IPv6 routes (rh #1086237) +- core: wait with startup-complete for dynamic IPv4 and IPv6 addresses (rh #1096063, rh #1086906) + * Thu May 1 2014 Dan Williams - 1:0.9.9.1-13.git20140326 - core: ignore IPv6 cache routes to fix initial connection generation (rh #1083153) - core: ensure slow DHCP emits 'dhcp4-change' and 'dhcp6-change' dispatcher events (rh #1091296) @@ -848,10 +898,10 @@ fi - NM no longer uses /var/run/NetworkManager, so don't claim to own it. (rh #656638) -* Wed May 2 2012 Jiří Klimeš - 0.9.4-3.git20120502%{?dist} +* Wed May 2 2012 Jiří Klimeš - 0.9.4-3.git20120502 - Update to git snapshot -* Wed Mar 28 2012 Colin Walters - 1:0.9.4-2.git20120328_2%{?dist} +* Wed Mar 28 2012 Colin Walters - 1:0.9.4-2.git20120328_2 - Add _isa for internal requires; otherwise depsolving may pull in an arbitrary architecture.