diff options
author | Pacho Ramos <pacho@gentoo.org> | 2016-09-17 16:27:18 +0200 |
---|---|---|
committer | Pacho Ramos <pacho@gentoo.org> | 2016-09-17 16:27:18 +0200 |
commit | 43f6353228bf92b8bf3d9a4c3b7d028130786be6 (patch) | |
tree | 1a0a1594e2175be63748f536270ead24b513cd64 /net-misc | |
parent | profiles/base/package.use.mask: mask no longer needed (diff) | |
download | gentoo-43f6353228bf92b8bf3d9a4c3b7d028130786be6.tar.gz gentoo-43f6353228bf92b8bf3d9a4c3b7d028130786be6.tar.bz2 gentoo-43f6353228bf92b8bf3d9a4c3b7d028130786be6.zip |
net-misc/networkmanager: Fix issues with wifi connection and dhcp (#593518 by Sven)
Package-Manager: portage-2.3.0
Diffstat (limited to 'net-misc')
4 files changed, 2443 insertions, 0 deletions
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 000000000000..53e146a5492d --- /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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 000000000000..9c1e774c448d --- /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 <thaller@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 <thaller@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 <thaller@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 <thaller@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 000000000000..2038b2f0fdca --- /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 <thaller@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 <thaller@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 000000000000..f1164896a1ef --- /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 +} |