commit:     43f6353228bf92b8bf3d9a4c3b7d028130786be6
Author:     Pacho Ramos <pacho <AT> gentoo <DOT> org>
AuthorDate: Sat Sep 17 14:27:18 2016 +0000
Commit:     Pacho Ramos <pacho <AT> gentoo <DOT> org>
CommitDate: Sat Sep 17 14:27:18 2016 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=43f63532

net-misc/networkmanager: Fix issues with wifi connection and dhcp (#593518 by 
Sven)

Package-Manager: portage-2.3.0

 .../files/networkmanager-1.4.0-dhcp-helper.patch   | 1570 ++++++++++++++++++++
 .../files/networkmanager-1.4.0-wifi-mac1.patch     |  245 +++
 .../files/networkmanager-1.4.0-wifi-mac2.patch     |  279 ++++
 .../networkmanager/networkmanager-1.4.0-r1.ebuild  |  349 +++++
 4 files changed, 2443 insertions(+)

diff --git 
a/net-misc/networkmanager/files/networkmanager-1.4.0-dhcp-helper.patch 
b/net-misc/networkmanager/files/networkmanager-1.4.0-dhcp-helper.patch
new file mode 100644
index 00000000..53e146a
--- /dev/null
+++ b/net-misc/networkmanager/files/networkmanager-1.4.0-dhcp-helper.patch
@@ -0,0 +1,1570 @@
+From a3d96601876e5dc34e68bf6777c770f83cac19fb Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Tue, 6 Sep 2016 10:56:32 +0200
+Subject: [PATCH 01/11] logging: don't round subsecond part in logging
+ timestamp
+
+tv.tv_usec is guaranteed to have less then 6 digits, however rounding it up
+we might reach 1000000 and thus the value becomes mis-aligned. To round
+correctly, we would have to carry over a potential overflow to the seconds.
+But that seems too much effort for little gain. Just truncate the value.
+
+(cherry picked from commit c1b4b99a3c758f320c369a8daadb219eeb50ee83)
+(cherry picked from commit 99e30bdf700220e98db76602645a9844360e3fab)
+---
+ src/nm-logging.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/nm-logging.c b/src/nm-logging.c
+index 3db8d20..6ecc160 100644
+--- a/src/nm-logging.c
++++ b/src/nm-logging.c
+@@ -512,7 +512,7 @@ _nm_log_impl (const char *file,
+       va_end (args);
+ 
+       g_get_current_time (&tv);
+-      nm_sprintf_buf (s_buf_timestamp, " [%ld.%04ld]", tv.tv_sec, (tv.tv_usec 
+ 50) / 100);
++      nm_sprintf_buf (s_buf_timestamp, " [%ld.%04ld]", tv.tv_sec, tv.tv_usec 
/ 100);
+ 
+       switch (global.log_backend) {
+ #if SYSTEMD_JOURNAL
+-- 
+2.7.4
+
+
+From b3bf5c5a771e1f105037323daa9f4e4696bce44c Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 14:12:41 +0200
+Subject: [PATCH 02/11] shared: add NM_MIN()/NM_MAX() macros to replace glib's
+ MIN()/MAX()
+
+(cherry picked from commit b2016fd2a52b82d45324526c965e7545d026cebe)
+(cherry picked from commit 811aaead4ca6f2f815f49b7353fa7a88554dca42)
+---
+ shared/nm-utils/nm-macros-internal.h | 44 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/shared/nm-utils/nm-macros-internal.h 
b/shared/nm-utils/nm-macros-internal.h
+index 73075c6..8811c91 100644
+--- a/shared/nm-utils/nm-macros-internal.h
++++ b/shared/nm-utils/nm-macros-internal.h
+@@ -526,6 +526,50 @@ nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, 
gpointer user_data)
+ 
+ 
/*****************************************************************************/
+ 
++/* Taken from systemd's UNIQ_T and UNIQ macros. */
++
++#define NM_UNIQ_T(x, uniq) G_PASTE(__unique_prefix_, G_PASTE(x, uniq))
++#define NM_UNIQ __COUNTER__
++
++/*****************************************************************************/
++
++/* glib's MIN()/MAX() macros don't have function-like behavior, in that they 
evaluate
++ * the argument possibly twice.
++ *
++ * Taken from systemd's MIN()/MAX() macros. */
++
++#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b)
++#define __NM_MIN(aq, a, bq, b) \
++      ({ \
++              typeof (a) NM_UNIQ_T(A, aq) = (a); \
++              typeof (b) NM_UNIQ_T(B, bq) = (b); \
++              ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : 
NM_UNIQ_T(B, bq)); \
++      })
++
++#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b)
++#define __NM_MAX(aq, a, bq, b) \
++      ({ \
++              typeof (a) NM_UNIQ_T(A, aq) = (a); \
++              typeof (b) NM_UNIQ_T(B, bq) = (b); \
++              ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : 
NM_UNIQ_T(B, bq)); \
++      })
++
++#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, 
high)
++#define __NM_CLAMP(xq, x, lowq, low, highq, high) \
++      ({ \
++              typeof(x)NM_UNIQ_T(X,xq) = (x); \
++              typeof(low) NM_UNIQ_T(LOW,lowq) = (low); \
++              typeof(high) NM_UNIQ_T(HIGH,highq) = (high); \
++              \
++              ( (NM_UNIQ_T(X,xq) > NM_UNIQ_T(HIGH,highq)) \
++                ? NM_UNIQ_T(HIGH,highq) \
++                : (NM_UNIQ_T(X,xq) < NM_UNIQ_T(LOW,lowq)) \
++                   ? NM_UNIQ_T(LOW,lowq) \
++                   : NM_UNIQ_T(X,xq)); \
++      })
++
++/*****************************************************************************/
++
+ static inline guint
+ nm_encode_version (guint major, guint minor, guint micro) {
+       /* analog to the preprocessor macro NM_ENCODE_VERSION(). */
+-- 
+2.7.4
+
+
+From d0b31408a5e1eeb7c3e09e3e79a90cf09c80b934 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 16:49:50 +0200
+Subject: [PATCH 03/11] shared: add _NM_GET_PRIVATE() macro
+
+(cherry picked from commit 2cae9ba348ed6ea4d41ebd714d8c55f4d49feae9)
+(cherry picked from commit 5bac57496c0ee458456f5cf68560263cea6c23de)
+---
+ shared/nm-utils/nm-macros-internal.h | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/shared/nm-utils/nm-macros-internal.h 
b/shared/nm-utils/nm-macros-internal.h
+index 8811c91..5b020e9 100644
+--- a/shared/nm-utils/nm-macros-internal.h
++++ b/shared/nm-utils/nm-macros-internal.h
+@@ -356,6 +356,24 @@ _notify (obj_type *obj, _PropertyEnums prop) \
+ 
+ 
/*****************************************************************************/
+ 
++#define __NM_GET_PRIVATE(self, type, is_check, result_cmd) \
++      ({ \
++              /* preserve the const-ness of self. Unfortunately, that
++               * way, @self cannot be a void pointer */ \
++              typeof (self) _self = (self); \
++              \
++              /* Get compiler error if variable is of wrong type */ \
++              _nm_unused const type *_self2 = (_self); \
++              \
++              nm_assert (is_check (_self)); \
++              ( result_cmd ); \
++      })
++
++#define _NM_GET_PRIVATE(self, type, is_check)     __NM_GET_PRIVATE(self, 
type, is_check, &_self->_priv)
++#define _NM_GET_PRIVATE_PTR(self, type, is_check) __NM_GET_PRIVATE(self, 
type, is_check,  _self->_priv)
++
++/*****************************************************************************/
++
+ static inline gpointer
+ nm_g_object_ref (gpointer obj)
+ {
+-- 
+2.7.4
+
+
+From 24d94264bdc6c036e732e201b167c1c7d20794e1 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 16:55:07 +0200
+Subject: [PATCH 04/11] core: use _NM_GET_PRIVATE() macros
+
+(cherry picked from commit cdf6ad40572f23be6f8b6971bd57b1002ffb9aaf)
+(cherry picked from commit 3940d63a7e6bff088bb3fb5e81c8cb2792b19b3a)
+---
+ src/devices/nm-device-ethernet.c    | 13 +------------
+ src/devices/nm-device-veth.c        | 13 +------------
+ src/devices/nm-device.c             | 31 ++++++++++---------------------
+ src/devices/nm-device.h             |  2 +-
+ src/devices/wifi/nm-device-wifi.c   | 13 +------------
+ src/devices/wifi/nm-wifi-ap.c       | 13 +------------
+ src/dns-manager/nm-dns-manager.c    | 13 +------------
+ src/nm-auth-subject.c               | 13 +------------
+ src/nm-checkpoint.c                 | 15 ++-------------
+ src/nm-ip4-config.c                 | 13 +------------
+ src/nm-ip6-config.c                 | 13 +------------
+ src/nm-manager.c                    | 15 ++-------------
+ src/rdisc/nm-lndp-rdisc.c           | 13 +------------
+ src/rdisc/nm-rdisc.c                | 13 +------------
+ src/vpn-manager/nm-vpn-connection.c | 13 +------------
+ 15 files changed, 26 insertions(+), 180 deletions(-)
+
+diff --git a/src/devices/nm-device-ethernet.c 
b/src/devices/nm-device-ethernet.c
+index 90d472d..b213a0c 100644
+--- a/src/devices/nm-device-ethernet.c
++++ b/src/devices/nm-device-ethernet.c
+@@ -127,18 +127,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceEthernet,
+ 
+ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
+ 
+-#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMDeviceEthernet *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_DEVICE_ETHERNET (_self)); \
+-              _self->_priv; \
+-      })
++#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, 
NMDeviceEthernet, NM_IS_DEVICE_ETHERNET)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c
+index cca86fb..5692331 100644
+--- a/src/devices/nm-device-veth.c
++++ b/src/devices/nm-device-veth.c
+@@ -62,18 +62,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVeth,
+ 
+ G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET)
+ 
+-#define NM_DEVICE_VETH_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMDeviceVeth *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_DEVICE_VETH (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_DEVICE_VETH_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceVeth, 
NM_IS_DEVICE_VETH)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
+index 6939332..674563f 100644
+--- a/src/devices/nm-device.c
++++ b/src/devices/nm-device.c
+@@ -75,18 +75,7 @@ _LOG_DECLARE_SELF (NMDevice);
+ 
+ G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
+ 
+-#define NM_DEVICE_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMDevice *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_DEVICE (_self)); \
+-              _self->priv; \
+-      })
++#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, 
NM_IS_DEVICE)
+ 
+ enum {
+       STATE_CHANGED,
+@@ -2029,7 +2018,7 @@ link_type_compatible (NMDevice *self,
+               return FALSE;
+       }
+ 
+-      device_type = self->priv->link_type;
++      device_type = self->_priv->link_type;
+       if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) {
+               g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+                            "Needed link type 0x%x does not match the platform 
link type 0x%X",
+@@ -10058,7 +10047,7 @@ nm_device_set_unmanaged_by_user_udev (NMDevice *self)
+       int ifindex;
+       gboolean platform_unmanaged = FALSE;
+ 
+-      ifindex = self->priv->ifindex;
++      ifindex = self->_priv->ifindex;
+ 
+       if (   ifindex <= 0
+           || !nm_platform_link_get_unmanaged (NM_PLATFORM_GET, ifindex, 
&platform_unmanaged))
+@@ -10145,7 +10134,7 @@ nm_device_reapply_settings_immediately (NMDevice *self)
+       if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)),
+                      nm_setting_connection_get_zone (s_con_applied)) != 0) {
+ 
+-              version_id = nm_active_connection_version_id_bump 
((NMActiveConnection *) self->priv->act_request);
++              version_id = nm_active_connection_version_id_bump 
((NMActiveConnection *) self->_priv->act_request);
+               _LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id 
%llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (long long unsigned) version_id);
+ 
+               g_object_set (G_OBJECT (s_con_applied),
+@@ -10157,7 +10146,7 @@ nm_device_reapply_settings_immediately (NMDevice *self)
+ 
+       if ((metered = nm_setting_connection_get_metered (s_con_settings)) != 
nm_setting_connection_get_metered (s_con_applied)) {
+ 
+-              version_id = nm_active_connection_version_id_bump 
((NMActiveConnection *) self->priv->act_request);
++              version_id = nm_active_connection_version_id_bump 
((NMActiveConnection *) self->_priv->act_request);
+               _LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id 
%llu)", (int) metered, (long long unsigned) version_id);
+ 
+               g_object_set (G_OBJECT (s_con_applied),
+@@ -10336,22 +10325,22 @@ nm_device_check_connection_available (NMDevice *self,
+ static gboolean
+ available_connections_del_all (NMDevice *self)
+ {
+-      if (g_hash_table_size (self->priv->available_connections) == 0)
++      if (g_hash_table_size (self->_priv->available_connections) == 0)
+               return FALSE;
+-      g_hash_table_remove_all (self->priv->available_connections);
++      g_hash_table_remove_all (self->_priv->available_connections);
+       return TRUE;
+ }
+ 
+ static gboolean
+ available_connections_add (NMDevice *self, NMConnection *connection)
+ {
+-      return nm_g_hash_table_add (self->priv->available_connections, 
g_object_ref (connection));
++      return nm_g_hash_table_add (self->_priv->available_connections, 
g_object_ref (connection));
+ }
+ 
+ static gboolean
+ available_connections_del (NMDevice *self, NMConnection *connection)
+ {
+-      return g_hash_table_remove (self->priv->available_connections, 
connection);
++      return g_hash_table_remove (self->_priv->available_connections, 
connection);
+ }
+ 
+ static gboolean
+@@ -12097,7 +12086,7 @@ nm_device_init (NMDevice *self)
+ 
+       priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE, 
NMDevicePrivate);
+ 
+-      self->priv = priv;
++      self->_priv = priv;
+ 
+       priv->type = NM_DEVICE_TYPE_UNKNOWN;
+       priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
+diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
+index 34d31ca..be12ce7 100644
+--- a/src/devices/nm-device.h
++++ b/src/devices/nm-device.h
+@@ -125,7 +125,7 @@ struct _NMDevice {
+       NMExportedObject parent;
+ 
+       /* private */
+-      struct _NMDevicePrivate *priv;
++      struct _NMDevicePrivate *_priv;
+ };
+ 
+ /* The flags have an relaxing meaning, that means, specifying more flags, can 
make
+diff --git a/src/devices/wifi/nm-device-wifi.c 
b/src/devices/wifi/nm-device-wifi.c
+index 49c380a..f97e668 100644
+--- a/src/devices/wifi/nm-device-wifi.c
++++ b/src/devices/wifi/nm-device-wifi.c
+@@ -138,18 +138,7 @@ struct _NMDeviceWifiClass
+ 
+ G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
+ 
+-#define NM_DEVICE_WIFI_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMDeviceWifi *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_DEVICE_WIFI (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_DEVICE_WIFI_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceWifi, 
NM_IS_DEVICE_WIFI)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
+index e1beb85..2232f82 100644
+--- a/src/devices/wifi/nm-wifi-ap.c
++++ b/src/devices/wifi/nm-wifi-ap.c
+@@ -68,18 +68,7 @@ struct _NMAccessPointClass{
+       NMExportedObjectClass parent;
+ };
+ 
+-#define NM_AP_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMAccessPoint *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_AP (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_AP_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMAccessPoint, NM_IS_AP)
+ 
+ G_DEFINE_TYPE (NMAccessPoint, nm_ap, NM_TYPE_EXPORTED_OBJECT)
+ 
+diff --git a/src/dns-manager/nm-dns-manager.c 
b/src/dns-manager/nm-dns-manager.c
+index 3efd5ac..ce8f4d9 100644
+--- a/src/dns-manager/nm-dns-manager.c
++++ b/src/dns-manager/nm-dns-manager.c
+@@ -151,18 +151,7 @@ G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, 
G_TYPE_OBJECT)
+ 
+ NM_DEFINE_SINGLETON_INSTANCE (NMDnsManager);
+ 
+-#define NM_DNS_MANAGER_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMDnsManager *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_DNS_MANAGER (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_DNS_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDnsManager, 
NM_IS_DNS_MANAGER)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c
+index eb496b2..54d3595 100644
+--- a/src/nm-auth-subject.c
++++ b/src/nm-auth-subject.c
+@@ -68,18 +68,7 @@ struct _NMAuthSubjectClass {
+ 
+ G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT)
+ 
+-#define NM_AUTH_SUBJECT_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMAuthSubject *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_AUTH_SUBJECT (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_AUTH_SUBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, 
NMAuthSubject, NM_IS_AUTH_SUBJECT)
+ 
+ /**************************************************************/
+ 
+diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c
+index cb1adc3..605e070 100644
+--- a/src/nm-checkpoint.c
++++ b/src/nm-checkpoint.c
+@@ -70,7 +70,7 @@ typedef struct {
+ 
+ struct _NMCheckpoint {
+       NMExportedObject parent;
+-      NMCheckpointPrivate priv;
++      NMCheckpointPrivate _priv;
+ };
+ 
+ typedef struct {
+@@ -79,18 +79,7 @@ typedef struct {
+ 
+ G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_EXPORTED_OBJECT)
+ 
+-#define NM_CHECKPOINT_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMCheckpoint *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_CHECKPOINT (_self)); \
+-              &_self->priv; \
+-      })
++#define NM_CHECKPOINT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMCheckpoint, 
NM_IS_CHECKPOINT)
+ 
+ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+       PROP_DEVICES,
+diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
+index 22d1d07..a4d4361 100644
+--- a/src/nm-ip4-config.c
++++ b/src/nm-ip4-config.c
+@@ -68,18 +68,7 @@ struct _NMIP4ConfigClass {
+ 
+ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT)
+ 
+-#define NM_IP4_CONFIG_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMIP4Config *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_IP4_CONFIG (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_IP4_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP4Config, 
NM_IS_IP4_CONFIG)
+ 
+ /* internal guint32 are assigned to gobject properties of type uint. Ensure, 
that uint is large enough */
+ G_STATIC_ASSERT (sizeof (uint) >= sizeof (guint32));
+diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
+index ac9e6cd..8002d61 100644
+--- a/src/nm-ip6-config.c
++++ b/src/nm-ip6-config.c
+@@ -61,18 +61,7 @@ struct _NMIP6ConfigClass {
+ 
+ G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT)
+ 
+-#define NM_IP6_CONFIG_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMIP6Config *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_IP6_CONFIG (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_IP6_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP6Config, 
NM_IS_IP6_CONFIG)
+ 
+ NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config,
+       PROP_IFINDEX,
+diff --git a/src/nm-manager.c b/src/nm-manager.c
+index 5794bb9..9ad6517 100644
+--- a/src/nm-manager.c
++++ b/src/nm-manager.c
+@@ -158,21 +158,10 @@ typedef struct {
+       NMExportedObjectClass parent;
+ } NMManagerClass;
+ 
+-#define NM_MANAGER_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMManager *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_MANAGER (_self)); \
+-              &_self->_priv; \
+-      })
+-
+ G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
+ 
++#define NM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMManager, 
NM_IS_MANAGER)
++
+ enum {
+       DEVICE_ADDED,
+       INTERNAL_DEVICE_ADDED,
+diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c
+index 12c2e30..db2965b 100644
+--- a/src/rdisc/nm-lndp-rdisc.c
++++ b/src/rdisc/nm-lndp-rdisc.c
+@@ -60,18 +60,7 @@ struct _NMLndpRDiscClass {
+ 
+ G_DEFINE_TYPE (NMLndpRDisc, nm_lndp_rdisc, NM_TYPE_RDISC)
+ 
+-#define NM_LNDP_RDISC_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMLndpRDisc *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_LNDP_RDISC (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_LNDP_RDISC_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMLndpRDisc, 
NM_IS_LNDP_RDISC)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
+index cf993bc..3bc6975 100644
+--- a/src/rdisc/nm-rdisc.c
++++ b/src/rdisc/nm-rdisc.c
+@@ -87,18 +87,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
+ 
+ G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT)
+ 
+-#define NM_RDISC_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMRDisc *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_RDISC (_self)); \
+-              _self->_priv; \
+-      })
++#define NM_RDISC_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMRDisc, 
NM_IS_RDISC)
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/vpn-manager/nm-vpn-connection.c 
b/src/vpn-manager/nm-vpn-connection.c
+index 92c5bd8..69b45dc 100644
+--- a/src/vpn-manager/nm-vpn-connection.c
++++ b/src/vpn-manager/nm-vpn-connection.c
+@@ -168,18 +168,7 @@ struct _NMVpnConnectionClass {
+ 
+ G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION)
+ 
+-#define NM_VPN_CONNECTION_GET_PRIVATE(self) \
+-      ({ \
+-              /* preserve the const-ness of self. Unfortunately, that
+-               * way, @self cannot be a void pointer */ \
+-              typeof (self) _self = (self); \
+-              \
+-              /* Get compiler error if variable is of wrong type */ \
+-              _nm_unused const NMVpnConnection *_self2 = (_self); \
+-              \
+-              nm_assert (NM_IS_VPN_CONNECTION (_self)); \
+-              &_self->_priv; \
+-      })
++#define NM_VPN_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE(self, 
NMVpnConnection, NM_IS_VPN_CONNECTION)
+ 
+ 
/*****************************************************************************/
+ 
+-- 
+2.7.4
+
+
+From f25940f2518c3789a5f18d1b458e53a95dc88af7 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 16:42:59 +0200
+Subject: [PATCH 05/11] dhcp-listener: refactor type definition and embed
+ private data in @self
+
+(cherry picked from commit 822f01a8fdb63831c887d5db9fb06eb840f53c88)
+(cherry picked from commit 75e13f0e15b7618d7fafbe3f1b990871be0950a7)
+---
+ src/dhcp-manager/nm-dhcp-listener.c | 50 +++++++++++++++++++++----------------
+ src/dhcp-manager/nm-dhcp-listener.h |  4 +--
+ 2 files changed, 31 insertions(+), 23 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-listener.c 
b/src/dhcp-manager/nm-dhcp-listener.c
+index eadff3e..d3616cb 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.c
++++ b/src/dhcp-manager/nm-dhcp-listener.c
+@@ -13,12 +13,14 @@
+  * with this program; if not, write to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+- * Copyright 2014 Red Hat, Inc.
++ * Copyright 2014 - 2016 Red Hat, Inc.
+  *
+  */
+ 
+ #include "nm-default.h"
+ 
++#include "nm-dhcp-listener.h"
++
+ #include <sys/socket.h>
+ #include <sys/wait.h>
+ #include <signal.h>
+@@ -27,7 +29,6 @@
+ #include <errno.h>
+ #include <unistd.h>
+ 
+-#include "nm-dhcp-listener.h"
+ #include "nm-core-internal.h"
+ #include "nm-bus-manager.h"
+ #include "NetworkManagerUtils.h"
+@@ -36,6 +37,8 @@
+ #define PRIV_SOCK_PATH            NMRUNDIR "/private-dhcp"
+ #define PRIV_SOCK_TAG             "dhcp"
+ 
++/*****************************************************************************/
++
+ typedef struct {
+       NMBusManager *      dbus_mgr;
+       gulong              new_conn_id;
+@@ -43,17 +46,26 @@ typedef struct {
+       GHashTable *        signal_handlers;
+ } NMDhcpListenerPrivate;
+ 
+-#define NM_DHCP_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
NM_TYPE_DHCP_LISTENER, NMDhcpListenerPrivate))
++struct _NMDhcpListener {
++      GObject parent;
++      NMDhcpListenerPrivate _priv;
++};
++
++struct _NMDhcpListenerClass {
++      GObjectClass parent_class;
++};
+ 
+ G_DEFINE_TYPE (NMDhcpListener, nm_dhcp_listener, G_TYPE_OBJECT)
+ 
++#define NM_DHCP_LISTENER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, 
NMDhcpListener, NM_IS_DHCP_LISTENER)
++
+ enum {
+       EVENT,
+       LAST_SIGNAL
+ };
+ static guint signals[LAST_SIGNAL] = { 0 };
+ 
+-/***************************************************/
++/*****************************************************************************/
+ 
+ static char *
+ get_option (GVariant *options, const char *key)
+@@ -188,7 +200,7 @@ nm_dhcp_listener_init (NMDhcpListener *self)
+ {
+       NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self);
+ 
+-      /* Maps GDBusConnection :: GDBusProxy */
++      /* Maps GDBusConnection :: signal-id */
+       priv->signal_handlers = g_hash_table_new (NULL, NULL);
+ 
+       priv->dbus_mgr = nm_bus_manager_get ();
+@@ -208,7 +220,7 @@ nm_dhcp_listener_init (NMDhcpListener *self)
+ static void
+ dispose (GObject *object)
+ {
+-      NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (object);
++      NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE 
((NMDhcpListener *) object);
+ 
+       nm_clear_g_signal_handler (priv->dbus_mgr, &priv->new_conn_id);
+       nm_clear_g_signal_handler (priv->dbus_mgr, &priv->dis_conn_id);
+@@ -224,22 +236,18 @@ nm_dhcp_listener_class_init (NMDhcpListenerClass 
*listener_class)
+ {
+       GObjectClass *object_class = G_OBJECT_CLASS (listener_class);
+ 
+-      g_type_class_add_private (listener_class, sizeof 
(NMDhcpListenerPrivate));
+-
+-      /* virtual methods */
+       object_class->dispose = dispose;
+ 
+-      /* signals */
+       signals[EVENT] =
+-              g_signal_new (NM_DHCP_LISTENER_EVENT,
+-                            G_OBJECT_CLASS_TYPE (object_class),
+-                            G_SIGNAL_RUN_LAST, 0,
+-                            g_signal_accumulator_true_handled,
+-                            NULL, NULL,
+-                            G_TYPE_BOOLEAN,     /* listeners return TRUE if 
handled */
+-                            4,
+-                            G_TYPE_STRING,      /* iface */
+-                            G_TYPE_INT,         /* pid */
+-                            G_TYPE_VARIANT,     /* options */
+-                            G_TYPE_STRING);     /* reason */
++          g_signal_new (NM_DHCP_LISTENER_EVENT,
++                        G_OBJECT_CLASS_TYPE (object_class),
++                        G_SIGNAL_RUN_LAST, 0,
++                        g_signal_accumulator_true_handled,
++                        NULL, NULL,
++                        G_TYPE_BOOLEAN,     /* listeners return TRUE if 
handled */
++                        4,
++                        G_TYPE_STRING,      /* iface */
++                        G_TYPE_INT,         /* pid */
++                        G_TYPE_VARIANT,     /* options */
++                        G_TYPE_STRING);     /* reason */
+ }
+diff --git a/src/dhcp-manager/nm-dhcp-listener.h 
b/src/dhcp-manager/nm-dhcp-listener.h
+index ff31fe3..3018b97 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.h
++++ b/src/dhcp-manager/nm-dhcp-listener.h
+@@ -26,8 +26,8 @@
+ 
+ #define NM_DHCP_LISTENER_EVENT "event"
+ 
+-typedef GObject NMDhcpListener;
+-typedef GObjectClass NMDhcpListenerClass;
++typedef struct _NMDhcpListener NMDhcpListener;
++typedef struct _NMDhcpListenerClass NMDhcpListenerClass;
+ 
+ GType nm_dhcp_listener_get_type (void);
+ 
+-- 
+2.7.4
+
+
+From 6d59141bd7459320a63ba606587d757cbd0aa74d Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 17:17:09 +0200
+Subject: [PATCH 06/11] dhcp-listener: add logging macros to nm-dhcp-listener.c
+
+(cherry picked from commit d37cd04fe059e9d99c7103f4e22a9a945f8d4d98)
+(cherry picked from commit 3920a90e4a63b69bda583c28cc6bdfef1a9f0470)
+---
+ src/dhcp-manager/nm-dhcp-listener.c | 39 ++++++++++++++++++++++++++-----------
+ 1 file changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-listener.c 
b/src/dhcp-manager/nm-dhcp-listener.c
+index d3616cb..79d3513 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.c
++++ b/src/dhcp-manager/nm-dhcp-listener.c
+@@ -55,16 +55,35 @@ struct _NMDhcpListenerClass {
+       GObjectClass parent_class;
+ };
+ 
+-G_DEFINE_TYPE (NMDhcpListener, nm_dhcp_listener, G_TYPE_OBJECT)
+-
+-#define NM_DHCP_LISTENER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, 
NMDhcpListener, NM_IS_DHCP_LISTENER)
+-
+ enum {
+       EVENT,
+       LAST_SIGNAL
+ };
+ static guint signals[LAST_SIGNAL] = { 0 };
+ 
++G_DEFINE_TYPE (NMDhcpListener, nm_dhcp_listener, G_TYPE_OBJECT)
++
++#define NM_DHCP_LISTENER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, 
NMDhcpListener, NM_IS_DHCP_LISTENER)
++
++NM_DEFINE_SINGLETON_GETTER (NMDhcpListener, nm_dhcp_listener_get, 
NM_TYPE_DHCP_LISTENER);
++
++/*****************************************************************************/
++
++#define _NMLOG_PREFIX_NAME    "dhcp-listener"
++#define _NMLOG_DOMAIN         LOGD_DHCP
++#define _NMLOG(level, ...) \
++    G_STMT_START { \
++        const NMDhcpListener *_self = (self); \
++        char _prefix[64]; \
++        \
++        nm_log ((level), (_NMLOG_DOMAIN), \
++                "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
++                (_self != singleton_instance \
++                    ? nm_sprintf_buf (_prefix, "%s[%p]", _NMLOG_PREFIX_NAME, 
_self) \
++                    : _NMLOG_PREFIX_NAME )\
++                _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
++    } G_STMT_END
++
+ 
/*****************************************************************************/
+ 
+ static char *
+@@ -123,20 +142,20 @@ handle_event (GDBusConnection  *connection,
+ 
+       iface = get_option (options, "interface");
+       if (iface == NULL) {
+-              nm_log_warn (LOGD_DHCP, "dhcp-event: didn't have associated 
interface.");
++              _LOGW ("dhcp-event: didn't have associated interface.");
+               goto out;
+       }
+ 
+       pid_str = get_option (options, "pid");
+       pid = _nm_utils_ascii_str_to_int64 (pid_str, 10, 0, G_MAXINT32, -1);
+       if (pid == -1) {
+-              nm_log_warn (LOGD_DHCP, "dhcp-event: couldn't convert PID '%s' 
to an integer", pid_str ? pid_str : "(null)");
++              _LOGW ("dhcp-event: couldn't convert PID '%s' to an integer", 
pid_str ? pid_str : "(null)");
+               goto out;
+       }
+ 
+       reason = get_option (options, "reason");
+       if (reason == NULL) {
+-              nm_log_warn (LOGD_DHCP, "dhcp-event: (pid %d) DHCP event didn't 
have a reason", pid);
++              _LOGW ("dhcp-event: (pid %d) DHCP event didn't have a reason", 
pid);
+               goto out;
+       }
+ 
+@@ -144,9 +163,9 @@ handle_event (GDBusConnection  *connection,
+       if (!handled) {
+               if (g_ascii_strcasecmp (reason, "RELEASE") == 0) {
+                       /* Ignore event when the dhcp client gets killed and we 
receive its last message */
+-                      nm_log_dbg (LOGD_DHCP, "dhcp-event: (pid %d) unhandled 
RELEASE DHCP event for interface %s", pid, iface);
++                      _LOGD ("dhcp-event: (pid %d) unhandled RELEASE DHCP 
event for interface %s", pid, iface);
+               } else
+-                      nm_log_warn (LOGD_DHCP, "dhcp-event: (pid %d) unhandled 
DHCP event for interface %s", pid, iface);
++                      _LOGW ("dhcp-event: (pid %d) unhandled DHCP event for 
interface %s", pid, iface);
+       }
+ 
+ out:
+@@ -193,8 +212,6 @@ dis_connection_cb (NMBusManager *mgr,
+ 
+ /***************************************************/
+ 
+-NM_DEFINE_SINGLETON_GETTER (NMDhcpListener, nm_dhcp_listener_get, 
NM_TYPE_DHCP_LISTENER);
+-
+ static void
+ nm_dhcp_listener_init (NMDhcpListener *self)
+ {
+-- 
+2.7.4
+
+
+From 5ac925ed8c718aa9ec0ab405680ed858fd79f8a6 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 17:24:28 +0200
+Subject: [PATCH 07/11] dhcp-listener/trivial: rename field to track
+ connections in NMDhcpListener
+
+It's not "signal-handles", as it currently tracks the registration ID of
+type int. Rename it, it is effectively the list of connections that we
+track.
+
+(cherry picked from commit 2dd3a5245f91a7c25ae1a36a86638195500f00a8)
+(cherry picked from commit 0ebdfd6cf1f1ba3c9753db4d9dd8979bb458a689)
+---
+ src/dhcp-manager/nm-dhcp-listener.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-listener.c 
b/src/dhcp-manager/nm-dhcp-listener.c
+index 79d3513..b09bc20 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.c
++++ b/src/dhcp-manager/nm-dhcp-listener.c
+@@ -43,7 +43,7 @@ typedef struct {
+       NMBusManager *      dbus_mgr;
+       gulong              new_conn_id;
+       gulong              dis_conn_id;
+-      GHashTable *        signal_handlers;
++      GHashTable *        connections;
+ } NMDhcpListenerPrivate;
+ 
+ struct _NMDhcpListener {
+@@ -192,7 +192,7 @@ new_connection_cb (NMBusManager *mgr,
+                                                NULL,
+                                                G_DBUS_SIGNAL_FLAGS_NONE,
+                                                handle_event, self, NULL);
+-      g_hash_table_insert (priv->signal_handlers, connection, 
GUINT_TO_POINTER (id));
++      g_hash_table_insert (priv->connections, connection, GUINT_TO_POINTER 
(id));
+ }
+ 
+ static void
+@@ -203,10 +203,10 @@ dis_connection_cb (NMBusManager *mgr,
+       NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self);
+       guint id;
+ 
+-      id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->signal_handlers, 
connection));
++      id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->connections, 
connection));
+       if (id) {
+               g_dbus_connection_signal_unsubscribe (connection, id);
+-              g_hash_table_remove (priv->signal_handlers, connection);
++              g_hash_table_remove (priv->connections, connection);
+       }
+ }
+ 
+@@ -218,7 +218,7 @@ nm_dhcp_listener_init (NMDhcpListener *self)
+       NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self);
+ 
+       /* Maps GDBusConnection :: signal-id */
+-      priv->signal_handlers = g_hash_table_new (NULL, NULL);
++      priv->connections = g_hash_table_new (NULL, NULL);
+ 
+       priv->dbus_mgr = nm_bus_manager_get ();
+ 
+@@ -243,7 +243,7 @@ dispose (GObject *object)
+       nm_clear_g_signal_handler (priv->dbus_mgr, &priv->dis_conn_id);
+       priv->dbus_mgr = NULL;
+ 
+-      g_clear_pointer (&priv->signal_handlers, g_hash_table_destroy);
++      g_clear_pointer (&priv->connections, g_hash_table_destroy);
+ 
+       G_OBJECT_CLASS (nm_dhcp_listener_parent_class)->dispose (object);
+ }
+-- 
+2.7.4
+
+
+From 35518c37de240061c26364b98e464ba140dcdc69 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 11:06:04 +0200
+Subject: [PATCH 08/11] dhcp-helper: refactor error handling
+
+Don't exit(1) from fatal_error() because that skips destroying
+local variables in main(). Just return regularly.
+
+(cherry picked from commit bb489163db36889a6fb80789e4e5b9dd8a15dbdd)
+(cherry picked from commit a8d87ef87f2931f07e6fa6dd0df56bf3d1fdf79e)
+---
+ src/dhcp-manager/nm-dhcp-helper.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-helper.c 
b/src/dhcp-manager/nm-dhcp-helper.c
+index 7667084..8c512e7 100644
+--- a/src/dhcp-manager/nm-dhcp-helper.c
++++ b/src/dhcp-manager/nm-dhcp-helper.c
+@@ -74,26 +74,26 @@ build_signal_parameters (void)
+ }
+ 
+ static void
+-fatal_error (void)
++kill_pid (void)
+ {
+-      const char *pid_str = getenv ("pid");
+-      int pid = 0;
++      const char *pid_str;
++      pid_t pid = 0;
+ 
++      pid_str = getenv ("pid");
+       if (pid_str)
+               pid = strtol (pid_str, NULL, 10);
+       if (pid) {
+               g_printerr ("Fatal error occured, killing dhclient instance 
with pid %d.\n", pid);
+               kill (pid, SIGTERM);
+       }
+-
+-      exit (1);
+ }
+ 
+ int
+ main (int argc, char *argv[])
+ {
+-      GDBusConnection *connection;
+-      GError *error = NULL;
++      gs_unref_object GDBusConnection *connection = NULL;
++      gs_free_error GError *error = NULL;
++      gboolean success = FALSE;
+ 
+       nm_g_type_init ();
+ 
+@@ -104,8 +104,7 @@ main (int argc, char *argv[])
+               g_dbus_error_strip_remote_error (error);
+               g_printerr ("Error: could not connect to NetworkManager D-Bus 
socket: %s\n",
+                           error->message);
+-              g_error_free (error);
+-              fatal_error ();
++              goto out;
+       }
+ 
+       if (!g_dbus_connection_emit_signal (connection,
+@@ -117,18 +116,19 @@ main (int argc, char *argv[])
+                                           &error)) {
+               g_dbus_error_strip_remote_error (error);
+               g_printerr ("Error: Could not send DHCP Event signal: %s\n", 
error->message);
+-              g_error_free (error);
+-              fatal_error ();
++              goto out;
+       }
+ 
+       if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
+               g_dbus_error_strip_remote_error (error);
+               g_printerr ("Error: Could not flush D-Bus connection: %s\n", 
error->message);
+-              g_error_free (error);
+-              fatal_error ();
++              goto out;
+       }
+ 
+-      g_object_unref (connection);
+-      return 0;
++      success = TRUE;
++out:
++      if (!success)
++              kill_pid ();
++      return success ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-- 
+2.7.4
+
+
+From e342765675214ef1fbcdd9e30d916c687a75fd6e Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 13:38:58 +0200
+Subject: [PATCH 09/11] dhcp-helper: refactor logging to use logging macros
+
+(cherry picked from commit cc89996c9e826c9c8d12d5fb7bc8a2a578209eb0)
+(cherry picked from commit 9d44dafc3cef8fe1b7d41c9af0f6fa30254924f1)
+---
+ src/dhcp-manager/nm-dhcp-helper.c | 45 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 40 insertions(+), 5 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-helper.c 
b/src/dhcp-manager/nm-dhcp-helper.c
+index 8c512e7..383c985 100644
+--- a/src/dhcp-manager/nm-dhcp-helper.c
++++ b/src/dhcp-manager/nm-dhcp-helper.c
+@@ -25,8 +25,43 @@
+ #include <string.h>
+ #include <signal.h>
+ 
++#include "nm-utils/nm-vpn-plugin-macros.h"
++
+ #define NM_DHCP_CLIENT_DBUS_IFACE   "org.freedesktop.nm_dhcp_client"
+ 
++/*****************************************************************************/
++
++#ifdef NM_MORE_LOGGING
++#define _NMLOG_ENABLED(level) TRUE
++#else
++#define _NMLOG_ENABLED(level) ((level) <= LOG_ERR)
++#endif
++
++#define _NMLOG(always_enabled, level, ...) \
++      G_STMT_START { \
++              if ((always_enabled) || _NMLOG_ENABLED (level)) { \
++                      GTimeVal _tv; \
++                      \
++                      g_get_current_time (&_tv); \
++                      g_print ("nm-dhcp-helper[%ld] %-7s [%ld.%04ld] " 
_NM_UTILS_MACRO_FIRST (__VA_ARGS__) "\n", \
++                               (long) getpid (), \
++                               nm_utils_syslog_to_str (level), \
++                               _tv.tv_sec, _tv.tv_usec / 100 \
++                               _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
++              } \
++      } G_STMT_END
++
++#define _LOGD(...) _NMLOG(TRUE,  LOG_INFO,    __VA_ARGS__)
++#define _LOGI(...) _NMLOG(TRUE,  LOG_NOTICE,  __VA_ARGS__)
++#define _LOGW(...) _NMLOG(TRUE,  LOG_WARNING, __VA_ARGS__)
++#define _LOGE(...) _NMLOG(TRUE,  LOG_ERR,     __VA_ARGS__)
++
++#define _LOGd(...) _NMLOG(FALSE, LOG_INFO,    __VA_ARGS__)
++#define _LOGi(...) _NMLOG(FALSE, LOG_NOTICE,  __VA_ARGS__)
++#define _LOGw(...) _NMLOG(FALSE, LOG_WARNING, __VA_ARGS__)
++
++/*****************************************************************************/
++
+ static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", 
NULL};
+ 
+ static GVariant *
+@@ -83,7 +118,7 @@ kill_pid (void)
+       if (pid_str)
+               pid = strtol (pid_str, NULL, 10);
+       if (pid) {
+-              g_printerr ("Fatal error occured, killing dhclient instance 
with pid %d.\n", pid);
++              _LOGI ("a fatal error occured, kill dhclient instance with pid 
%d\n", pid);
+               kill (pid, SIGTERM);
+       }
+ }
+@@ -102,8 +137,8 @@ main (int argc, char *argv[])
+                                                            NULL, NULL, 
&error);
+       if (!connection) {
+               g_dbus_error_strip_remote_error (error);
+-              g_printerr ("Error: could not connect to NetworkManager D-Bus 
socket: %s\n",
+-                          error->message);
++              _LOGE ("could not connect to NetworkManager D-Bus socket: %s",
++                     error->message);
+               goto out;
+       }
+ 
+@@ -115,13 +150,13 @@ main (int argc, char *argv[])
+                                           build_signal_parameters (),
+                                           &error)) {
+               g_dbus_error_strip_remote_error (error);
+-              g_printerr ("Error: Could not send DHCP Event signal: %s\n", 
error->message);
++              _LOGE ("could not send DHCP Event signal: %s", error->message);
+               goto out;
+       }
+ 
+       if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
+               g_dbus_error_strip_remote_error (error);
+-              g_printerr ("Error: Could not flush D-Bus connection: %s\n", 
error->message);
++              _LOGE ("could not flush D-Bus connection: %s", error->message);
+               goto out;
+       }
+ 
+-- 
+2.7.4
+
+
+From 8fb42bd50ad41167498332e48bea548cdf76453c Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 11:54:46 +0200
+Subject: [PATCH 10/11] dhcp: add new header "nm-dhcp-helper-api.h"
+
+(cherry picked from commit 7684b68c49812ed7b2ec493889fae04db066b665)
+(cherry picked from commit 3ac3125aff9987b3ac0284daaa3faae93291a603)
+---
+ src/Makefile.am                       |  1 +
+ src/dhcp-manager/Makefile.am          |  5 ++++-
+ src/dhcp-manager/nm-dhcp-helper-api.h | 31 +++++++++++++++++++++++++++++++
+ src/dhcp-manager/nm-dhcp-helper.c     |  2 +-
+ src/dhcp-manager/nm-dhcp-listener.c   |  2 +-
+ 5 files changed, 38 insertions(+), 3 deletions(-)
+ create mode 100644 src/dhcp-manager/nm-dhcp-helper-api.h
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index c460caf..8d29b19 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -335,6 +335,7 @@ libNetworkManager_la_SOURCES = \
+       dhcp-manager/nm-dhcp-client.c \
+       dhcp-manager/nm-dhcp-client.h \
+       dhcp-manager/nm-dhcp-client-logging.h \
++      dhcp-manager/nm-dhcp-helper-api.h \
+       dhcp-manager/nm-dhcp-utils.c \
+       dhcp-manager/nm-dhcp-utils.h \
+       dhcp-manager/nm-dhcp-listener.c \
+diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am
+index b4590b4..4295412 100644
+--- a/src/dhcp-manager/Makefile.am
++++ b/src/dhcp-manager/Makefile.am
+@@ -1,6 +1,9 @@
+ libexec_PROGRAMS = nm-dhcp-helper
+ 
+-nm_dhcp_helper_SOURCES = nm-dhcp-helper.c
++nm_dhcp_helper_SOURCES = \
++      nm-dhcp-helper.c \
++      nm-dhcp-helper-api.h \
++      $(NULL)
+ 
+ nm_dhcp_helper_CPPFLAGS = \
+       $(GLIB_CFLAGS) \
+diff --git a/src/dhcp-manager/nm-dhcp-helper-api.h 
b/src/dhcp-manager/nm-dhcp-helper-api.h
+new file mode 100644
+index 0000000..a6323db
+--- /dev/null
++++ b/src/dhcp-manager/nm-dhcp-helper-api.h
+@@ -0,0 +1,31 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++/* NetworkManager -- Network link manager
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301 USA.
++ *
++ * (C) Copyright 2016 Red Hat, Inc.
++ */
++
++#ifndef __NM_DHCP_HELPER_API_H__
++#define __NM_DHCP_HELPER_API_H__
++
++/******************************************************************************/
++
++#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
++
++/******************************************************************************/
++
++#endif /* __NM_DHCP_HELPER_API_H__ */
+diff --git a/src/dhcp-manager/nm-dhcp-helper.c 
b/src/dhcp-manager/nm-dhcp-helper.c
+index 383c985..e53fe27 100644
+--- a/src/dhcp-manager/nm-dhcp-helper.c
++++ b/src/dhcp-manager/nm-dhcp-helper.c
+@@ -27,7 +27,7 @@
+ 
+ #include "nm-utils/nm-vpn-plugin-macros.h"
+ 
+-#define NM_DHCP_CLIENT_DBUS_IFACE   "org.freedesktop.nm_dhcp_client"
++#include "nm-dhcp-helper-api.h"
+ 
+ 
/*****************************************************************************/
+ 
+diff --git a/src/dhcp-manager/nm-dhcp-listener.c 
b/src/dhcp-manager/nm-dhcp-listener.c
+index b09bc20..7e9de49 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.c
++++ b/src/dhcp-manager/nm-dhcp-listener.c
+@@ -29,11 +29,11 @@
+ #include <errno.h>
+ #include <unistd.h>
+ 
++#include "nm-dhcp-helper-api.h"
+ #include "nm-core-internal.h"
+ #include "nm-bus-manager.h"
+ #include "NetworkManagerUtils.h"
+ 
+-#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
+ #define PRIV_SOCK_PATH            NMRUNDIR "/private-dhcp"
+ #define PRIV_SOCK_TAG             "dhcp"
+ 
+-- 
+2.7.4
+
+
+From 901ac5654ae51fd44b575c21201f41f5e6f2bbd8 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 5 Sep 2016 12:32:40 +0200
+Subject: [PATCH 11/11] dhcp: call synchronous Notify D-Bus method from
+ nm-dhcp-helper
+
+A D-Bus signal is asynchronous and it can happen that nm-dhcp-helper
+emits the "Event" signal before the server is able to register a handler:
+
+   NM_DHCP_HELPER=/usr/libexec/nm-dhcp-helper
+   nmcli general logging level TRACE
+   for i in `seq 1 500`; do $NM_DHCP_HELPER & done
+   journalctl -u NetworkManager --since '1 min ago' | grep "didn't have 
associated interface" | wc -l
+    499
+
+Avoid that, by calling the synchronous D-Bus method "Notify".
+
+Interestingly, this race seem to exist since 2007.
+
+Actually, we called g_dbus_connection_signal_subscribe() from inside
+GDBusServer:new-connection signal. So it is not clear how such a race
+could exist. I was not able to reproduce it by putting a sleep
+before g_dbus_connection_signal_subscribe(). On the other hand, there
+is bug rh#1372854 and above reproducer which strongly indicates that
+events can be lost under certain circumstances.
+Now we instead g_dbus_connection_register_object() from the
+new-connection signal. According to my tests there was no more race
+as also backed by glib's documentation. Still, keep a simple retry-loop
+in nm-dhcp-helper just to be sure.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1372854
+https://bugzilla.redhat.com/show_bug.cgi?id=1373276
+(cherry picked from commit 2856a658b38df88494187c811415a198a424e1f2)
+(cherry picked from commit e678bd29a4e5fdd83b7d99392d54ecb5fcabc287)
+---
+ src/dhcp-manager/nm-dhcp-helper-api.h |  5 ++
+ src/dhcp-manager/nm-dhcp-helper.c     | 78 +++++++++++++++++++++++-----
+ src/dhcp-manager/nm-dhcp-listener.c   | 97 ++++++++++++++++++++++++++++-------
+ src/nm-bus-manager.c                  |  6 ++-
+ 4 files changed, 153 insertions(+), 33 deletions(-)
+
+diff --git a/src/dhcp-manager/nm-dhcp-helper-api.h 
b/src/dhcp-manager/nm-dhcp-helper-api.h
+index a6323db..a3eb171 100644
+--- a/src/dhcp-manager/nm-dhcp-helper-api.h
++++ b/src/dhcp-manager/nm-dhcp-helper-api.h
+@@ -26,6 +26,11 @@
+ 
+ #define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
+ 
++#define NM_DHCP_HELPER_SERVER_BUS_NAME          
"org.freedesktop.nm_dhcp_server"
++#define NM_DHCP_HELPER_SERVER_OBJECT_PATH       
"/org/freedesktop/nm_dhcp_server"
++#define NM_DHCP_HELPER_SERVER_INTERFACE_NAME    
"org.freedesktop.nm_dhcp_server"
++#define NM_DHCP_HELPER_SERVER_METHOD_NOTIFY     "Notify"
++
+ 
/******************************************************************************/
+ 
+ #endif /* __NM_DHCP_HELPER_API_H__ */
+diff --git a/src/dhcp-manager/nm-dhcp-helper.c 
b/src/dhcp-manager/nm-dhcp-helper.c
+index e53fe27..9c6f69b 100644
+--- a/src/dhcp-manager/nm-dhcp-helper.c
++++ b/src/dhcp-manager/nm-dhcp-helper.c
+@@ -105,7 +105,7 @@ build_signal_parameters (void)
+               g_free (name);
+       }
+ 
+-      return g_variant_new ("(a{sv})", &builder);
++      return g_variant_ref_sink (g_variant_new ("(a{sv})", &builder));
+ }
+ 
+ static void
+@@ -128,7 +128,11 @@ main (int argc, char *argv[])
+ {
+       gs_unref_object GDBusConnection *connection = NULL;
+       gs_free_error GError *error = NULL;
++      gs_unref_variant GVariant *parameters = NULL;
++      gs_unref_variant GVariant *result = NULL;
+       gboolean success = FALSE;
++      guint try_count = 0;
++      gint64 time_end;
+ 
+       nm_g_type_init ();
+ 
+@@ -142,25 +146,73 @@ main (int argc, char *argv[])
+               goto out;
+       }
+ 
+-      if (!g_dbus_connection_emit_signal (connection,
+-                                          NULL,
+-                                          "/",
+-                                          NM_DHCP_CLIENT_DBUS_IFACE,
+-                                          "Event",
+-                                          build_signal_parameters (),
+-                                          &error)) {
+-              g_dbus_error_strip_remote_error (error);
+-              _LOGE ("could not send DHCP Event signal: %s", error->message);
+-              goto out;
+-      }
++      parameters = build_signal_parameters ();
++
++      time_end = g_get_monotonic_time () + (200 * 1000L); /* retry for at 
most 200 milliseconds */
++
++do_notify:
++      try_count++;
++      result = g_dbus_connection_call_sync (connection,
++                                            NULL,
++                                            NM_DHCP_HELPER_SERVER_OBJECT_PATH,
++                                            
NM_DHCP_HELPER_SERVER_INTERFACE_NAME,
++                                            
NM_DHCP_HELPER_SERVER_METHOD_NOTIFY,
++                                            parameters,
++                                            NULL,
++                                            G_DBUS_CALL_FLAGS_NONE,
++                                            1000,
++                                            NULL,
++                                            &error);
++
++      if (!result) {
++              gs_free char *s_err = NULL;
++
++              s_err = g_dbus_error_get_remote_error (error);
++              if (NM_IN_STRSET (s_err, 
"org.freedesktop.DBus.Error.UnknownMethod")) {
++                      gint64 remaining_time = time_end - g_get_monotonic_time 
();
++
++                      /* I am not sure that a race can actually happen, as we 
register the object
++                       * on the server side during GDBusServer:new-connection 
signal.
++                       *
++                       * However, there was also a race for subscribing to an 
event, so let's just
++                       * do some retry. */
++                      if (remaining_time > 0) {
++                              _LOGi ("failure to call notify: %s (retry %u)", 
error->message, try_count);
++                              g_usleep (NM_MIN (NM_CLAMP ((gint64) (100L * 
(1L << try_count)), 5000, 25000), remaining_time));
++                              g_clear_error (&error);
++                              goto do_notify;
++                      }
++              }
++              _LOGW ("failure to call notify: %s (try signal via Event)", 
error->message);
++              g_clear_error (&error);
++
++              /* for backward compatibilty, try to emit the signal. There is 
no stable
++               * API between the dhcp-helper and NetworkManager. However, 
while upgrading
++               * the NetworkManager package, a newer helper might want to 
notify an
++               * older server, which still uses the "Event". */
++              if (!g_dbus_connection_emit_signal (connection,
++                                                  NULL,
++                                                  "/",
++                                                  NM_DHCP_CLIENT_DBUS_IFACE,
++                                                  "Event",
++                                                  parameters,
++                                                  &error)) {
++                      g_dbus_error_strip_remote_error (error);
++                      _LOGE ("could not send DHCP Event signal: %s", 
error->message);
++                      goto out;
++              }
++              /* We were able to send the asynchronous Event. Consider that a 
success. */
++              success = TRUE;
++      } else
++              success = TRUE;
+ 
+       if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
+               g_dbus_error_strip_remote_error (error);
+               _LOGE ("could not flush D-Bus connection: %s", error->message);
++              success = FALSE;
+               goto out;
+       }
+ 
+-      success = TRUE;
+ out:
+       if (!success)
+               kill_pid ();
+diff --git a/src/dhcp-manager/nm-dhcp-listener.c 
b/src/dhcp-manager/nm-dhcp-listener.c
+index 7e9de49..0df4197 100644
+--- a/src/dhcp-manager/nm-dhcp-listener.c
++++ b/src/dhcp-manager/nm-dhcp-listener.c
+@@ -119,13 +119,14 @@ get_option (GVariant *options, const char *key)
+ }
+ 
+ static void
+-handle_event (GDBusConnection  *connection,
+-              const char       *sender_name,
+-              const char       *object_path,
+-              const char       *interface_name,
+-              const char       *signal_name,
+-              GVariant         *parameters,
+-              gpointer          user_data)
++_method_call (GDBusConnection *connection,
++              const char *sender,
++              const char *object_path,
++              const char *interface_name,
++              const char *method_name,
++              GVariant *parameters,
++              GDBusMethodInvocation *invocation,
++              gpointer user_data)
+ {
+       NMDhcpListener *self = NM_DHCP_LISTENER (user_data);
+       char *iface = NULL;
+@@ -135,8 +136,12 @@ handle_event (GDBusConnection  *connection,
+       gboolean handled = FALSE;
+       GVariant *options;
+ 
++      if (!nm_streq0 (interface_name, NM_DHCP_HELPER_SERVER_INTERFACE_NAME))
++              g_return_if_reached ();
++      if (!nm_streq0 (method_name, NM_DHCP_HELPER_SERVER_METHOD_NOTIFY))
++              g_return_if_reached ();
+       if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
+-              return;
++              g_return_if_reached ();
+ 
+       g_variant_get (parameters, "(@a{sv})", &options);
+ 
+@@ -173,6 +178,57 @@ out:
+       g_free (pid_str);
+       g_free (reason);
+       g_variant_unref (options);
++      g_dbus_method_invocation_return_value (invocation, NULL);
++}
++
++static guint
++_dbus_connection_register_object (NMDhcpListener *self,
++                                  GDBusConnection *connection,
++                                  GError **error)
++{
++      static GDBusArgInfo arg_info_notify_in = {
++              .ref_count = -1,
++              .name = "data",
++              .signature = "a{sv}",
++              .annotations = NULL,
++      };
++      static GDBusArgInfo *arg_infos_notify[] = {
++              &arg_info_notify_in,
++              NULL,
++      };
++      static GDBusMethodInfo method_info_notify = {
++              .ref_count = -1,
++              .name = NM_DHCP_HELPER_SERVER_METHOD_NOTIFY,
++              .in_args = arg_infos_notify,
++              .out_args = NULL,
++              .annotations = NULL,
++      };
++      static GDBusMethodInfo *method_infos[] = {
++              &method_info_notify,
++              NULL,
++      };
++      static GDBusInterfaceInfo interface_info = {
++              .ref_count = -1,
++              .name = NM_DHCP_HELPER_SERVER_INTERFACE_NAME,
++              .methods = method_infos,
++              .signals = NULL,
++              .properties = NULL,
++              .annotations = NULL,
++      };
++
++      static GDBusInterfaceVTable interface_vtable = {
++              .method_call = _method_call,
++              .get_property = NULL,
++              .set_property = NULL,
++      };
++
++      return g_dbus_connection_register_object (connection,
++                                                
NM_DHCP_HELPER_SERVER_OBJECT_PATH,
++                                                &interface_info,
++                                                &interface_vtable,
++                                                self,
++                                                NULL,
++                                                error);
+ }
+ 
+ static void
+@@ -182,17 +238,20 @@ new_connection_cb (NMBusManager *mgr,
+                    NMDhcpListener *self)
+ {
+       NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self);
+-      guint id;
++      guint registration_id;
++      GError *error = NULL;
++
++      /* it is important to register the object during the new-connection 
signal,
++       * as this avoids races with the connecting object. */
++      registration_id = _dbus_connection_register_object (self, connection, 
&error);
++      if (!registration_id) {
++              _LOGE ("failure to register %s for connection %p: %s",
++                     NM_DHCP_HELPER_SERVER_OBJECT_PATH, connection, 
error->message);
++              g_error_free (error);
++              return;
++      }
+ 
+-      id = g_dbus_connection_signal_subscribe (connection,
+-                                               NULL,
+-                                               NM_DHCP_CLIENT_DBUS_IFACE,
+-                                               "Event",
+-                                               NULL,
+-                                               NULL,
+-                                               G_DBUS_SIGNAL_FLAGS_NONE,
+-                                               handle_event, self, NULL);
+-      g_hash_table_insert (priv->connections, connection, GUINT_TO_POINTER 
(id));
++      g_hash_table_insert (priv->connections, connection, GUINT_TO_POINTER 
(registration_id));
+ }
+ 
+ static void
+@@ -205,7 +264,7 @@ dis_connection_cb (NMBusManager *mgr,
+ 
+       id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->connections, 
connection));
+       if (id) {
+-              g_dbus_connection_signal_unsubscribe (connection, id);
++              g_dbus_connection_unregister_object (connection, id);
+               g_hash_table_remove (priv->connections, connection);
+       }
+ }
+diff --git a/src/nm-bus-manager.c b/src/nm-bus-manager.c
+index 449de4e..270792e 100644
+--- a/src/nm-bus-manager.c
++++ b/src/nm-bus-manager.c
+@@ -221,7 +221,11 @@ private_server_new_connection (GDBusServer *server,
+ 
+       _LOGD ("(%s) accepted connection %p on private socket", s->tag, conn);
+ 
+-      /* Emit this for the manager */
++      /* Emit this for the manager.
++       *
++       * It is essential to do this from the "new-connection" signal handler, 
as
++       * at that point no messages from the connection are yet processed
++       * (which avoids races with registering objects). */
+       g_signal_emit (s->manager,
+                      signals[PRIVATE_CONNECTION_NEW],
+                      s->detail,
+-- 
+2.7.4
+

diff --git a/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac1.patch 
b/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac1.patch
new file mode 100644
index 00000000..9c1e774
--- /dev/null
+++ b/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac1.patch
@@ -0,0 +1,245 @@
+From c52f385566e558ee3edc98d20225155b362d212f Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Sun, 28 Aug 2016 13:52:32 +0200
+Subject: [PATCH 1/4] platform: split processing result from do_change_link()
+
+(cherry picked from commit 3dc09446771a3434ed948bdd5e6ca9f6ef9a9e76)
+(cherry picked from commit 471521ca84187cd32afcd20aebe5a369fe7368dc)
+---
+ src/platform/nm-linux-platform.c | 35 +++++++++++++++++++++++++++--------
+ 1 file changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/src/platform/nm-linux-platform.c 
b/src/platform/nm-linux-platform.c
+index 98c4e46..eeb24ca 100644
+--- a/src/platform/nm-linux-platform.c
++++ b/src/platform/nm-linux-platform.c
+@@ -4060,18 +4060,14 @@ out:
+       return !!nmp_cache_lookup_obj (priv->cache, obj_id);
+ }
+ 
+-static NMPlatformError
+-do_change_link (NMPlatform *platform,
+-                int ifindex,
+-                struct nl_msg *nlmsg)
++static WaitForNlResponseResult
++do_change_link_request (NMPlatform *platform,
++                        int ifindex,
++                        struct nl_msg *nlmsg)
+ {
+       nm_auto_pop_netns NMPNetns *netns = NULL;
+       WaitForNlResponseResult seq_result = 
WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
+       int nle;
+-      char s_buf[256];
+-      NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
+-      NMLogLevel log_level = LOGL_DEBUG;
+-      const char *log_result = "failure", *log_detail = "";
+ 
+       if (!nm_platform_netns_push (platform, &netns))
+               return NM_PLATFORM_ERROR_UNSPECIFIED;
+@@ -4098,6 +4094,18 @@ retry:
+               nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
+               goto retry;
+       }
++      return seq_result;
++}
++
++static NMPlatformError
++do_change_link_result (NMPlatform *platform,
++                       int ifindex,
++                       WaitForNlResponseResult seq_result)
++{
++      char s_buf[256];
++      NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
++      NMLogLevel log_level = LOGL_DEBUG;
++      const char *log_result = "failure", *log_detail = "";
+ 
+       if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
+               log_result = "success";
+@@ -4123,6 +4131,17 @@ retry:
+       return result;
+ }
+ 
++static NMPlatformError
++do_change_link (NMPlatform *platform,
++                int ifindex,
++                struct nl_msg *nlmsg)
++{
++      WaitForNlResponseResult seq_result;
++
++      seq_result = do_change_link_request (platform, ifindex, nlmsg);
++      return do_change_link_result (platform, ifindex, seq_result);
++}
++
+ static gboolean
+ link_add (NMPlatform *platform,
+           const char *name,
+-- 
+2.7.4
+
+
+From 559ed361a30650f263668aadb86233fb405f0b29 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Sun, 28 Aug 2016 14:08:42 +0200
+Subject: [PATCH 2/4] platform: workaround kernel wrongly returning ENFILE when
+ changing MAC address
+
+https://bugzilla.gnome.org/show_bug.cgi?id=770456
+(cherry picked from commit 2bef71611bd9fd2e333a7522205f0262ac25680f)
+(cherry picked from commit 06d1679aa9867682297316e7b2cfac6fc8f67c2a)
+---
+ src/platform/nm-linux-platform.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/src/platform/nm-linux-platform.c 
b/src/platform/nm-linux-platform.c
+index eeb24ca..c36e967 100644
+--- a/src/platform/nm-linux-platform.c
++++ b/src/platform/nm-linux-platform.c
+@@ -4449,6 +4449,8 @@ link_set_address (NMPlatform *platform, int ifindex, 
gconstpointer address, size
+ {
+       nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+       gs_free char *mac = NULL;
++      WaitForNlResponseResult seq_result;
++      char s_buf[256];
+ 
+       if (!address || !length)
+               g_return_val_if_reached (NM_PLATFORM_ERROR_BUG);
+@@ -4468,7 +4470,30 @@ link_set_address (NMPlatform *platform, int ifindex, 
gconstpointer address, size
+ 
+       NLA_PUT (nlmsg, IFLA_ADDRESS, length, address);
+ 
+-      return do_change_link (platform, ifindex, nlmsg);
++      seq_result = do_change_link_request (platform, ifindex, nlmsg);
++
++      if (NM_IN_SET (-((int) seq_result), ENFILE)) {
++              const NMPObject *obj_cache;
++
++              /* workaround ENFILE which may be wrongly returned (bgo 
#770456).
++               * If the MAC address is as expected, assume success? */
++
++              obj_cache = nmp_cache_lookup_link 
(NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, ifindex);
++              if (   obj_cache
++                  && obj_cache->link.addr.len == length
++                  && memcmp (obj_cache->link.addr.data, address, length) == 
0) {
++                      _NMLOG (LOGL_DEBUG,
++                              "do-change-link[%d]: %s changing link: %s%s",
++                              ifindex,
++                              "success",
++                              wait_for_nl_response_to_string (seq_result, 
s_buf, sizeof (s_buf)),
++                              " (assume success changing address)");
++                      return NM_PLATFORM_ERROR_SUCCESS;
++              }
++      }
++
++      return do_change_link_result (platform, ifindex, seq_result);
++
+ nla_put_failure:
+       g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED);
+ }
+-- 
+2.7.4
+
+
+From afe1a15516f0a5024f161e3ff1046afdfb7e58b8 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 29 Aug 2016 17:14:04 +0200
+Subject: [PATCH 3/4] device: fix spelling in logging
+
+(cherry picked from commit d51f2c2a4e99799739e2adbeaf578144b556c4b9)
+(cherry picked from commit b1f5d3d798498c53fe65257490b2df3e3f71e364)
+---
+ src/devices/nm-device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
+index 199acc6..305a1bb 100644
+--- a/src/devices/nm-device.c
++++ b/src/devices/nm-device.c
+@@ -11820,7 +11820,7 @@ _hw_addr_set (NMDevice *self,
+                              operation, addr, detail);
+               } else {
+                       _LOGW (LOGD_DEVICE,
+-                             "set-hw-addr: new MAC address %s not 
successfully set to %s (%s)",
++                             "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
+                              addr, operation, detail);
+                       success = FALSE;
+               }
+-- 
+2.7.4
+
+
+From ac81b54da92c569db110407a63142565d69963f4 Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Mon, 29 Aug 2016 18:28:34 +0200
+Subject: [PATCH 4/4] device: add hack to wait after changing MAC address
+
+It seems some drivers return success for nm_platform_link_set_address(),
+but at that point the address did not yet actually change *sigh*.
+It changes a bit later, possibly after setting the device up.
+
+Add a workaround to retry reading the MAC address when platform indicates
+success but the address still differs at first.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=770456
+(cherry picked from commit 67b685235847ac49712d77023e23ef5c38e82a9e)
+(cherry picked from commit 3b51959f48f2b40a4d85e1d36fd69a46548369cb)
+---
+ src/devices/nm-device.c | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
+index 305a1bb..6939332 100644
+--- a/src/devices/nm-device.c
++++ b/src/devices/nm-device.c
+@@ -11774,6 +11774,7 @@ _hw_addr_set (NMDevice *self,
+ {
+       NMDevicePrivate *priv;
+       gboolean success = FALSE;
++      gboolean needs_refresh = FALSE;
+       NMPlatformError plerr;
+       const char *cur_addr;
+       guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
+@@ -11819,10 +11820,10 @@ _hw_addr_set (NMDevice *self,
+                       _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s 
(%s)",
+                              operation, addr, detail);
+               } else {
+-                      _LOGW (LOGD_DEVICE,
+-                             "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
++                      _LOGD (LOGD_DEVICE,
++                             "set-hw-addr: new MAC address %s not 
successfully %s (%s) (refresh link)",
+                              addr, operation, detail);
+-                      success = FALSE;
++                      needs_refresh = TRUE;
+               }
+       } else {
+               _NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : 
LOGL_WARN,
+@@ -11836,6 +11837,27 @@ _hw_addr_set (NMDevice *self,
+                       return FALSE;
+       }
+ 
++      if (needs_refresh) {
++              /* The platform call indicated success, however the address is 
not
++               * as expected. May be a kernel issue and the MAC address takes
++               * a moment to change (bgo#770456).
++               *
++               * Try to reload the link and check again. */
++              nm_platform_link_refresh (NM_PLATFORM_GET, 
nm_device_get_ip_ifindex (self));
++
++              nm_device_update_hw_address (self);
++              cur_addr = nm_device_get_hw_address (self);
++              if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, 
-1)) {
++                      _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s 
(%s)",
++                             operation, addr, detail);
++              } else {
++                      _LOGW (LOGD_DEVICE,
++                             "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
++                             addr, operation, detail);
++                      return FALSE;
++              }
++      }
++
+       return success;
+ }
+ 
+-- 
+2.7.4
+

diff --git a/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac2.patch 
b/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac2.patch
new file mode 100644
index 00000000..2038b2f
--- /dev/null
+++ b/net-misc/networkmanager/files/networkmanager-1.4.0-wifi-mac2.patch
@@ -0,0 +1,279 @@
+From 3c701b60dc169a24cf52c0397560125ddce3d54c Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Wed, 7 Sep 2016 23:47:14 +0200
+Subject: [PATCH 1/2] device: workaround driver issue with delayed change of
+ MAC address
+
+brcmfmac and possibly other drivers don't change the MAC address
+right away, but instead the result is delayed. That is problematic
+because we cannot continue activation before the MAC address is
+settled.
+
+Add a hack to workaround the issue by waiting until the MAC address
+changed.
+
+The previous attempt to workaround this was less intrusive: we would
+just refresh the link once and check the result. But that turns out
+not to be sufficent for all cases. Now, wait and poll.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=770456
+https://bugzilla.redhat.com/show_bug.cgi?id=1374023
+(cherry picked from commit 1a85103765d4eaa0acab6b03658a4f9cfe684a64)
+(cherry picked from commit 8d575403685208aad75f918484ae7adbc1a46085)
+---
+ src/devices/nm-device.c | 85 ++++++++++++++++++++++++++++++++++---------------
+ src/devices/nm-device.h |  2 +-
+ 2 files changed, 61 insertions(+), 26 deletions(-)
+
+diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
+index 674563f..3e549c5 100644
+--- a/src/devices/nm-device.c
++++ b/src/devices/nm-device.c
+@@ -11549,16 +11549,17 @@ nm_device_get_hw_address (NMDevice *self)
+       return priv->hw_addr;
+ }
+ 
+-void
++gboolean
+ nm_device_update_hw_address (NMDevice *self)
+ {
+       NMDevicePrivate *priv;
+       const guint8 *hwaddr;
+       gsize hwaddrlen = 0;
++      gboolean changed = FALSE;
+ 
+       priv = NM_DEVICE_GET_PRIVATE (self);
+       if (priv->ifindex <= 0)
+-              return;
++              return FALSE;
+ 
+       hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, 
&hwaddrlen);
+ 
+@@ -11585,6 +11586,7 @@ nm_device_update_hw_address (NMDevice *self)
+                                * update our inital hw-address as well. */
+                               nm_device_update_initial_hw_address (self);
+                       }
++                      changed = TRUE;
+               }
+       } else {
+               /* Invalid or no hardware address */
+@@ -11597,6 +11599,7 @@ nm_device_update_hw_address (NMDevice *self)
+                              "hw-addr: failed reading current MAC address");
+               }
+       }
++      return changed;
+ }
+ 
+ void
+@@ -11756,6 +11759,15 @@ nm_device_hw_addr_is_explict (NMDevice *self)
+ }
+ 
+ static gboolean
++_hw_addr_matches (NMDevice *self, const char *addr)
++{
++      const char *cur_addr;
++
++      cur_addr = nm_device_get_hw_address (self);
++      return cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1);
++}
++
++static gboolean
+ _hw_addr_set (NMDevice *self,
+               const char *addr,
+               const char *operation,
+@@ -11765,7 +11777,6 @@ _hw_addr_set (NMDevice *self,
+       gboolean success = FALSE;
+       gboolean needs_refresh = FALSE;
+       NMPlatformError plerr;
+-      const char *cur_addr;
+       guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
+       guint hw_addr_len;
+       gboolean was_up;
+@@ -11776,11 +11787,9 @@ _hw_addr_set (NMDevice *self,
+ 
+       priv = NM_DEVICE_GET_PRIVATE (self);
+ 
+-      cur_addr = nm_device_get_hw_address (self);
+-
+       /* Do nothing if current MAC is same */
+-      if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
+-              _LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed 
(%s)", cur_addr);
++      if (_hw_addr_matches (self, addr)) {
++              _LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed 
(%s)", addr);
+               return TRUE;
+       }
+ 
+@@ -11804,8 +11813,7 @@ _hw_addr_set (NMDevice *self,
+       if (success) {
+               /* MAC address succesfully changed; update the current MAC to 
match */
+               nm_device_update_hw_address (self);
+-              cur_addr = nm_device_get_hw_address (self);
+-              if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, 
-1)) {
++              if (_hw_addr_matches (self, addr)) {
+                       _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s 
(%s)",
+                              operation, addr, detail);
+               } else {
+@@ -11827,24 +11835,51 @@ _hw_addr_set (NMDevice *self,
+       }
+ 
+       if (needs_refresh) {
+-              /* The platform call indicated success, however the address is 
not
+-               * as expected. May be a kernel issue and the MAC address takes
+-               * a moment to change (bgo#770456).
+-               *
+-               * Try to reload the link and check again. */
+-              nm_platform_link_refresh (NM_PLATFORM_GET, 
nm_device_get_ip_ifindex (self));
+-
+-              nm_device_update_hw_address (self);
+-              cur_addr = nm_device_get_hw_address (self);
+-              if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, 
-1)) {
+-                      _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s 
(%s)",
+-                             operation, addr, detail);
++              if (_hw_addr_matches (self, addr)) {
++                      /* the MAC address already changed during 
nm_device_bring_up() above. */
+               } else {
+-                      _LOGW (LOGD_DEVICE,
+-                             "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
+-                             addr, operation, detail);
+-                      return FALSE;
++                      gint64 poll_end, now;
++
++                      /* The platform call indicated success, however the 
address is not
++                       * as expected. That is either due to a driver issue 
(brcmfmac, bgo#770456,
++                       * rh#1374023) or a race where externally the MAC 
address was reset.
++                       * The race is rather unlikely.
++                       *
++                       * The alternative would be to postpone the activation 
in case the
++                       * MAC address is not yet ready and poll without 
blocking. However,
++                       * that is rather complicated and it is not expected 
that this case
++                       * happens for regular drivers.
++                       * Note that brcmfmac can block NetworkManager for 500 
msec while
++                       * taking down the device. Let's add annother 100 msec 
to that.
++                       *
++                       * wait/poll up to 100 msec until it changes. */
++
++                      poll_end = nm_utils_get_monotonic_timestamp_us () + 
(100 * 1000);
++                      for (;;) {
++                              if (!nm_platform_link_refresh (NM_PLATFORM_GET, 
nm_device_get_ip_ifindex (self)))
++                                      goto handle_fail;
++                              if (!nm_device_update_hw_address (self))
++                                      goto handle_wait;
++                              if (!_hw_addr_matches (self, addr))
++                                      goto handle_fail;
++
++                              break;
++handle_wait:
++                              now = nm_utils_get_monotonic_timestamp_us ();
++                              if (now < poll_end) {
++                                      g_usleep (NM_MIN (poll_end - now, 500));
++                                      continue;
++                              }
++handle_fail:
++                              _LOGW (LOGD_DEVICE,
++                                     "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
++                                     addr, operation, detail);
++                              return FALSE;
++                      }
+               }
++
++              _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
++                     operation, addr, detail);
+       }
+ 
+       return success;
+diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
+index be12ce7..a757a37 100644
+--- a/src/devices/nm-device.h
++++ b/src/devices/nm-device.h
+@@ -588,7 +588,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device,
+                                       NMSettingIPConfig *s_ip6_old,
+                                       NMSettingIPConfig *s_ip6_new);
+ 
+-void nm_device_update_hw_address (NMDevice *self);
++gboolean nm_device_update_hw_address (NMDevice *self);
+ void nm_device_update_initial_hw_address (NMDevice *self);
+ void nm_device_update_permanent_hw_address (NMDevice *self);
+ void nm_device_update_dynamic_ip_setup (NMDevice *self);
+-- 
+2.7.4
+
+
+From d99c3b63e81347fb861e1306eb0b603cfa15223e Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thal...@redhat.com>
+Date: Sun, 11 Sep 2016 09:48:56 +0200
+Subject: [PATCH 2/2] device: wait for MAC address change to complete before
+ setting interface up
+
+Some drivers (brcmfmac) don't change the MAC address right away.
+NetworkManager works around that by waiting synchronously until
+the address changes (commit 1a85103765d4eaa0acab6b03658a4f9cfe684a64).
+
+wpa_supplicant on the other hand, only re-reads the MAC address
+when changing state from DISABLED to ENABLED, which happens when
+the interface comes up.
+
+That is a bug in wpa_supplicant and the driver, but we can work-around by
+waiting until the MAC address actually changed before setting the interface
+IFF_UP. Also note, that there is still a race in wpa_supplicant which might
+miss a change to DISABLED state altogether.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=770504
+https://bugzilla.redhat.com/show_bug.cgi?id=1374023
+(cherry picked from commit 32f7c1d4b9aba597a99128631f07c2985149f303)
+(cherry picked from commit cd8f2ecc617a896d8007e6fe825c676a626a3b8d)
+---
+ src/devices/nm-device.c | 27 ++++++++++++++++-----------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
+index 3e549c5..47e858b 100644
+--- a/src/devices/nm-device.c
++++ b/src/devices/nm-device.c
+@@ -11829,12 +11829,8 @@ _hw_addr_set (NMDevice *self,
+                       nm_platform_error_to_string (plerr));
+       }
+ 
+-      if (was_up) {
+-              if (!nm_device_bring_up (self, TRUE, NULL))
+-                      return FALSE;
+-      }
+-
+       if (needs_refresh) {
++              success = TRUE;
+               if (_hw_addr_matches (self, addr)) {
+                       /* the MAC address already changed during 
nm_device_bring_up() above. */
+               } else {
+@@ -11871,15 +11867,24 @@ handle_wait:
+                                       continue;
+                               }
+ handle_fail:
+-                              _LOGW (LOGD_DEVICE,
+-                                     "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
+-                                     addr, operation, detail);
+-                              return FALSE;
++                              success = FALSE;
++                              break;
+                       }
+               }
+ 
+-              _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
+-                     operation, addr, detail);
++              if (success) {
++                      _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s 
(%s)",
++                             operation, addr, detail);
++              } else {
++                      _LOGW (LOGD_DEVICE,
++                             "set-hw-addr: new MAC address %s not 
successfully %s (%s)",
++                             addr, operation, detail);
++              }
++      }
++
++      if (was_up) {
++              if (!nm_device_bring_up (self, TRUE, NULL))
++                      return FALSE;
+       }
+ 
+       return success;
+-- 
+2.7.4
+

diff --git a/net-misc/networkmanager/networkmanager-1.4.0-r1.ebuild 
b/net-misc/networkmanager/networkmanager-1.4.0-r1.ebuild
new file mode 100644
index 00000000..f116489
--- /dev/null
+++ b/net-misc/networkmanager/networkmanager-1.4.0-r1.ebuild
@@ -0,0 +1,349 @@
+# Copyright 1999-2016 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI=6
+GNOME_ORG_MODULE="NetworkManager"
+GNOME2_LA_PUNT="yes"
+VALA_USE_DEPEND="vapigen"
+PYTHON_COMPAT=( python{2_7,3_3,3_4,3_5} )
+
+inherit bash-completion-r1 gnome2 linux-info multilib python-any-r1 systemd \
+       user readme.gentoo-r1 toolchain-funcs vala versionator virtualx udev 
multilib-minimal
+
+DESCRIPTION="A set of co-operative tools that make networking simple and 
straightforward"
+HOMEPAGE="https://wiki.gnome.org/Projects/NetworkManager";
+
+LICENSE="GPL-2+"
+SLOT="0" # add subslot if libnm-util.so.2 or libnm-glib.so.4 bumps soname 
version
+
+IUSE="audit bluetooth connection-sharing consolekit +dhclient gnutls 
+introspection \
+json kernel_linux +nss +modemmanager ncurses ofono +ppp resolvconf selinux \
+systemd teamd test vala +wext +wifi"
+
+REQUIRED_USE="
+       modemmanager? ( ppp )
+       vala? ( introspection )
+       wext? ( wifi )
+       ^^ ( nss gnutls )
+"
+
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~ppc ~ppc64 ~x86"
+
+# gobject-introspection-0.10.3 is needed due to gnome bug 642300
+# wpa_supplicant-0.7.3-r3 is needed due to bug 359271
+# TODO: need multilib janson (linked to libnm.so)
+COMMON_DEPEND="
+       >=sys-apps/dbus-1.2[${MULTILIB_USEDEP}]
+       >=dev-libs/dbus-glib-0.100[${MULTILIB_USEDEP}]
+       >=dev-libs/glib-2.37.6:2[${MULTILIB_USEDEP}]
+       >=dev-libs/libnl-3.2.8:3=
+       >=sys-auth/polkit-0.106
+       net-libs/libndp
+       >=net-libs/libsoup-2.40:2.4=
+       net-misc/iputils
+       sys-libs/readline:0
+       >=virtual/libgudev-165:=[${MULTILIB_USEDEP}]
+       audit? ( sys-process/audit )
+       bluetooth? ( >=net-wireless/bluez-5 )
+       connection-sharing? (
+               net-dns/dnsmasq[dhcp]
+               net-firewall/iptables )
+       consolekit? ( >=sys-auth/consolekit-1.0.0 )
+       dhclient? ( >=net-misc/dhcp-4[client] )
+       gnutls? (
+               dev-libs/libgcrypt:0=[${MULTILIB_USEDEP}]
+               >=net-libs/gnutls-2.12:=[${MULTILIB_USEDEP}] )
+       introspection? ( >=dev-libs/gobject-introspection-0.10.3:= )
+       json? ( dev-libs/jansson )
+       modemmanager? ( >=net-misc/modemmanager-0.7.991 )
+       ncurses? ( >=dev-libs/newt-0.52.15 )
+       nss? ( >=dev-libs/nss-3.11:=[${MULTILIB_USEDEP}] )
+       ofono? ( net-misc/ofono )
+       ppp? ( >=net-dialup/ppp-2.4.5:=[ipv6] )
+       resolvconf? ( net-dns/openresolv )
+       selinux? ( sys-libs/libselinux )
+       systemd? ( >=sys-apps/systemd-209:0= )
+       !systemd? (
+               !consolekit? ( || ( sys-power/upower sys-power/upower-pm-utils 
) )
+       )
+       teamd? ( >=net-misc/libteam-1.9 )
+"
+RDEPEND="${COMMON_DEPEND}
+       wifi? ( >=net-wireless/wpa_supplicant-0.7.3-r3[dbus] )
+"
+DEPEND="${COMMON_DEPEND}
+       dev-util/gdbus-codegen
+       dev-util/gtk-doc-am
+       >=dev-util/intltool-0.40
+       >=sys-devel/gettext-0.17
+       >=sys-kernel/linux-headers-2.6.29
+       virtual/pkgconfig[${MULTILIB_USEDEP}]
+       vala? ( $(vala_depend) )
+       test? (
+               $(python_gen_any_dep '
+                       dev-python/dbus-python[${PYTHON_USEDEP}]
+                       dev-python/pygobject:3[${PYTHON_USEDEP}]')
+       )
+"
+
+PATCHES=(
+       # Fix with Fedora patches for:
+       # https://bugzilla.gnome.org/show_bug.cgi?id=770456
+       "${FILESDIR}"/${P}-wifi-mac{1,2}.patch
+       # and dhcp (both fixed in 1.4.1)
+       "${FILESDIR}"/${P}-dhcp-helper.patch
+)
+
+python_check_deps() {
+       if use test; then
+               has_version "dev-python/dbus-python[${PYTHON_USEDEP}]" &&
+               has_version "dev-python/pygobject:3[${PYTHON_USEDEP}]"
+       else
+               return 0
+       fi
+}
+
+sysfs_deprecated_check() {
+       ebegin "Checking for SYSFS_DEPRECATED support"
+
+       if { linux_chkconfig_present SYSFS_DEPRECATED_V2; }; then
+               eerror "Please disable SYSFS_DEPRECATED_V2 support in your 
kernel config and recompile your kernel"
+               eerror "or NetworkManager will not work correctly."
+               eerror "See https://bugs.gentoo.org/333639 for more info."
+               die "CONFIG_SYSFS_DEPRECATED_V2 support detected!"
+       fi
+       eend $?
+}
+
+pkg_pretend() {
+       if use kernel_linux; then
+               get_version
+               if linux_config_exists; then
+                       sysfs_deprecated_check
+               else
+                       ewarn "Was unable to determine your kernel .config"
+                       ewarn "Please note that if CONFIG_SYSFS_DEPRECATED_V2 
is set in your kernel .config, NetworkManager will not work correctly."
+                       ewarn "See https://bugs.gentoo.org/333639 for more 
info."
+               fi
+
+       fi
+}
+
+pkg_setup() {
+       enewgroup plugdev
+
+       use test && python-any-r1_pkg_setup
+}
+
+src_prepare() {
+       DOC_CONTENTS="To modify system network connections without needing to 
enter the
+               root password, add your user account to the 'plugdev' group."
+
+       use vala && vala_src_prepare
+       gnome2_src_prepare
+}
+
+multilib_src_configure() {
+       local myconf=()
+
+       # Same hack as net-dialup/pptpd to get proper plugin dir for ppp, bug 
#519986
+       if use ppp; then
+               local PPPD_VER=`best_version net-dialup/ppp`
+               PPPD_VER=${PPPD_VER#*/*-} #reduce it to ${PV}-${PR}
+               PPPD_VER=${PPPD_VER%%[_-]*} # main version without 
beta/pre/patch/revision
+               myconf+=( 
--with-pppd-plugin-dir=/usr/$(get_libdir)/pppd/${PPPD_VER} )
+       fi
+
+       # unit files directory needs to be passed only when systemd is enabled,
+       # otherwise systemd support is not disabled completely, bug #524534
+       use systemd && myconf+=( 
--with-systemdsystemunitdir="$(systemd_get_systemunitdir)" )
+
+       if multilib_is_native_abi; then
+               # work-around man out-of-source brokenness, must be done before 
configure
+               mkdir man || die
+               find "${S}"/man -name '*.?' -exec ln -s {} man/ ';' || die
+       else
+               # libnl, libndp are only used for executables, not libraries
+               myconf+=( LIB{NL,NDP}_{CFLAGS,LIBS}=' ' )
+       fi
+
+       # ifnet plugin always disabled until someone volunteers to actively
+       # maintain and fix it
+       # Also disable dhcpcd support as it's also completely unmaintained
+       # and facing bugs like #563938 and many others
+       #
+       # We need --with-libnm-glib (and dbus-glib dep) as reverse deps are
+       # still not ready for removing that lib
+       ECONF_SOURCE=${S} \
+       runstatedir="/run" \
+               gnome2_src_configure \
+               --disable-more-warnings \
+               --disable-static \
+               --localstatedir=/var \
+               --disable-lto \
+               --disable-config-plugin-ibft \
+               --disable-ifnet \
+               --disable-qt \
+               --without-netconfig \
+               --with-dbus-sys-dir=/etc/dbus-1/system.d \
+               --with-libnm-glib \
+               --with-nmcli=yes \
+               --with-udev-dir="$(get_udevdir)" \
+               --with-config-plugins-default=keyfile \
+               --with-iptables=/sbin/iptables \
+               $(multilib_native_with libsoup) \
+               $(multilib_native_enable concheck) \
+               --with-crypto=$(usex nss nss gnutls) \
+               --with-session-tracking=$(multilib_native_usex systemd systemd 
$(multilib_native_usex consolekit consolekit no)) \
+               --with-suspend-resume=$(multilib_native_usex systemd systemd 
$(multilib_native_usex consolekit consolekit upower)) \
+               $(multilib_native_use_with audit libaudit) \
+               $(multilib_native_use_enable bluetooth bluez5-dun) \
+               $(multilib_native_use_enable introspection) \
+               $(multilib_native_use_enable json json-validation) \
+               $(multilib_native_use_enable ppp) \
+               $(use_with dhclient) \
+               --without-dhcpcd \
+               $(multilib_native_use_with modemmanager modem-manager-1) \
+               $(multilib_native_use_with ncurses nmtui) \
+               $(multilib_native_use_with ofono) \
+               $(multilib_native_use_with resolvconf) \
+               $(multilib_native_use_with selinux) \
+               $(multilib_native_use_with systemd systemd-journal) \
+               $(multilib_native_use_enable teamd teamdctl) \
+               $(multilib_native_use_enable test tests) \
+               $(multilib_native_use_enable vala) \
+               --without-valgrind \
+               $(multilib_native_use_with wext) \
+               $(multilib_native_use_enable wifi) \
+               "${myconf[@]}"
+
+       # work-around gtk-doc out-of-source brokedness
+       if multilib_is_native_abi; then
+               local d
+               for d in api libnm libnm-util libnm-glib; do
+                       ln -s "${S}"/docs/${d}/html docs/${d}/html || die
+               done
+       fi
+
+       # Disable examples
+       # https://bugzilla.gnome.org/show_bug.cgi?id=769711
+       cat > examples/Makefile <<-EOF
+       .PHONY: all check install
+       all:
+       check:
+       install:
+       EOF
+}
+
+multilib_src_compile() {
+       if multilib_is_native_abi; then
+               emake
+       else
+               emake all-am
+               emake -C shared
+               emake -C introspection # generated headers, needed for libnm
+               emake -C libnm-core
+               emake -C libnm
+               emake -C libnm-util
+               emake -C libnm-glib
+       fi
+}
+
+multilib_src_test() {
+       if use test && multilib_is_native_abi; then
+               python_setup
+               virtx emake check
+       fi
+}
+
+multilib_src_install() {
+       if multilib_is_native_abi; then
+               # Install completions at proper place, bug #465100
+               gnome2_src_install completiondir="$(get_bashcompdir)"
+       else
+               emake DESTDIR="${D}" install-am
+               emake DESTDIR="${D}" install -C shared
+               emake DESTDIR="${D}" install -C introspection
+               emake DESTDIR="${D}" install -C libnm-core
+               emake DESTDIR="${D}" install -C libnm
+               emake DESTDIR="${D}" install -C libnm-util
+               emake DESTDIR="${D}" install -C libnm-glib
+       fi
+}
+
+multilib_src_install_all() {
+       ! use systemd && readme.gentoo_create_doc
+
+       newinitd "${FILESDIR}/init.d.NetworkManager" NetworkManager
+       newconfd "${FILESDIR}/conf.d.NetworkManager" NetworkManager
+
+       # Need to keep the /etc/NetworkManager/dispatched.d for dispatcher 
scripts
+       keepdir /etc/NetworkManager/dispatcher.d
+
+       # Provide openrc net dependency only when nm is connected
+       exeinto /etc/NetworkManager/dispatcher.d
+       newexe "${FILESDIR}/10-openrc-status-r4" 10-openrc-status
+       sed -e "s:@EPREFIX@:${EPREFIX}:g" \
+               -i "${ED}/etc/NetworkManager/dispatcher.d/10-openrc-status" || 
die
+
+       keepdir /etc/NetworkManager/system-connections
+       chmod 0600 "${ED}"/etc/NetworkManager/system-connections/.keep* # bug 
#383765, upstream bug #754594
+
+       # Allow users in plugdev group to modify system connections
+       insinto /usr/share/polkit-1/rules.d/
+       doins 
"${FILESDIR}/01-org.freedesktop.NetworkManager.settings.modify.system.rules"
+
+       # Remove empty /run/NetworkManager
+       rmdir "${D}"/run/NetworkManager "${D}"/run || die
+}
+
+pkg_postinst() {
+       gnome2_pkg_postinst
+       ! use systemd && readme.gentoo_print_elog
+
+       if [[ -e "${EROOT}etc/NetworkManager/nm-system-settings.conf" ]]; then
+               ewarn "The ${PN} system configuration file has moved to a new 
location."
+               ewarn "You must migrate your settings from 
${EROOT}/etc/NetworkManager/nm-system-settings.conf"
+               ewarn "to ${EROOT}etc/NetworkManager/NetworkManager.conf"
+               ewarn
+               ewarn "After doing so, you can remove 
${EROOT}etc/NetworkManager/nm-system-settings.conf"
+       fi
+
+       # The polkit rules file moved to /usr/share
+       
old_rules="${EROOT}etc/polkit-1/rules.d/01-org.freedesktop.NetworkManager.settings.modify.system.rules"
+       if [[ -f "${old_rules}" ]]; then
+               case "$(md5sum ${old_rules})" in
+                 574d0cfa7e911b1f7792077003060240* )
+                       # Automatically delete the old rules.d file if the user 
did not change it
+                       elog
+                       elog "Removing old ${old_rules} ..."
+                       rm -f "${old_rules}" || eerror "Failed, please remove 
${old_rules} manually"
+                       ;;
+                 * )
+                       elog "The ${old_rules}"
+                       elog "file moved to /usr/share/polkit-1/rules.d/ in 
>=networkmanager-0.9.4.0-r4"
+                       elog "If you edited ${old_rules}"
+                       elog "without changing its behavior, you may want to 
remove it."
+                       ;;
+               esac
+       fi
+
+       # NM fallbacks to plugin specified at compile time (upstream bug 
#738611)
+       # but still show a warning to remember people to have cleaner config 
file
+       if [[ -e "${EROOT}etc/NetworkManager/NetworkManager.conf" ]]; then
+               if grep plugins 
"${EROOT}etc/NetworkManager/NetworkManager.conf" | grep -q ifnet; then
+                       ewarn
+                       ewarn "You seem to use 'ifnet' plugin in 
${EROOT}etc/NetworkManager/NetworkManager.conf"
+                       ewarn "Since it won't be used, you will need to stop 
setting ifnet plugin there."
+                       ewarn
+               fi
+       fi
+
+       # NM shows lots of errors making nmcli neither unusable, bug #528748 
upstream bug #690457
+       if grep -r "psk-flags=1" "${EROOT}"/etc/NetworkManager/; then
+               ewarn "You have psk-flags=1 setting in above files, you will 
need to"
+               ewarn "either reconfigure affected networks or, at least, set 
the flag"
+               ewarn "value to '0'."
+       fi
+}

Reply via email to