diff options
| author | Michael Biebl <biebl@debian.org> | 2016-09-17 12:56:06 (GMT) |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-09-23 21:53:08 (GMT) |
| commit | 0bb216356b69f2df305b921c9e38a0a2bb502c4d (patch) | |
| tree | 11d7e13942af83bf43d34367a83b3358b215326e | |
| parent | 6ca68536b2eae7d93e2df2c73d63481c5828edbd (diff) | |
Fix MAC address randomization
Cherry-pick a couple of upstream commits which work around driver bugs
when MAC address randomization is used.
Closes: #835822
Closes: #835553
9 files changed, 570 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index bfa7708..6fd7e92 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,9 @@ network-manager (1.4.0-4) UNRELEASED; urgency=medium * Drop override for dh_auto_test. We don't explicitly need to dump the log files as dh_auto_test runs with VERBOSE=1 by default. + * Fix MAC address randomization. + Cherry-pick a couple of upstream commits which work around driver bugs + when MAC address randomization is used. (Closes: #835822, #835553) -- Michael Biebl <biebl@debian.org> Sat, 17 Sep 2016 14:51:02 +0200 diff --git a/debian/patches/device-add-hack-to-wait-after-changing-MAC-address.patch b/debian/patches/device-add-hack-to-wait-after-changing-MAC-address.patch new file mode 100644 index 0000000..94ae6a7 --- /dev/null +++ b/debian/patches/device-add-hack-to-wait-after-changing-MAC-address.patch @@ -0,0 +1,72 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Mon, 29 Aug 2016 18:28:34 +0200 +Subject: 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; + } + diff --git a/debian/patches/device-fix-spelling-in-logging.patch b/debian/patches/device-fix-spelling-in-logging.patch new file mode 100644 index 0000000..b6b1f50 --- /dev/null +++ b/debian/patches/device-fix-spelling-in-logging.patch @@ -0,0 +1,23 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Mon, 29 Aug 2016 17:14:04 +0200 +Subject: 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; + } diff --git a/debian/patches/device-wait-for-MAC-address-change-to-complete-before-set.patch b/debian/patches/device-wait-for-MAC-address-change-to-complete-before-set.patch new file mode 100644 index 0000000..8e5f29f --- /dev/null +++ b/debian/patches/device-wait-for-MAC-address-change-to-complete-before-set.patch @@ -0,0 +1,75 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Sun, 11 Sep 2016 09:48:56 +0200 +Subject: 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 6c720bb..dd77ccf 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -11840,12 +11840,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 { +@@ -11882,15 +11878,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; diff --git a/debian/patches/device-workaround-driver-issue-with-delayed-change-of-MAC.patch b/debian/patches/device-workaround-driver-issue-with-delayed-change-of-MAC.patch new file mode 100644 index 0000000..e764839 --- /dev/null +++ b/debian/patches/device-workaround-driver-issue-with-delayed-change-of-MAC.patch @@ -0,0 +1,194 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Wed, 7 Sep 2016 23:47:14 +0200 +Subject: 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 6939332..6c720bb 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -11560,16 +11560,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); + +@@ -11596,6 +11597,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 */ +@@ -11608,6 +11610,7 @@ nm_device_update_hw_address (NMDevice *self) + "hw-addr: failed reading current MAC address"); + } + } ++ return changed; + } + + void +@@ -11767,6 +11770,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, +@@ -11776,7 +11788,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; +@@ -11787,11 +11798,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; + } + +@@ -11815,8 +11824,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 { +@@ -11838,24 +11846,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 34d31ca..0f91b21 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); diff --git a/debian/patches/platform-split-processing-result-from-do_change_link.patch b/debian/patches/platform-split-processing-result-from-do_change_link.patch new file mode 100644 index 0000000..d8c1449 --- /dev/null +++ b/debian/patches/platform-split-processing-result-from-do_change_link.patch @@ -0,0 +1,74 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Sun, 28 Aug 2016 13:52:32 +0200 +Subject: 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, diff --git a/debian/patches/platform-workaround-kernel-wrongly-returning-ENFILE-when-.patch b/debian/patches/platform-workaround-kernel-wrongly-returning-ENFILE-when-.patch new file mode 100644 index 0000000..bcf4c0b --- /dev/null +++ b/debian/patches/platform-workaround-kernel-wrongly-returning-ENFILE-when-.patch @@ -0,0 +1,57 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Sun, 28 Aug 2016 14:08:42 +0200 +Subject: 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); + } diff --git a/debian/patches/series b/debian/patches/series index 404165c..eafd037 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -5,3 +5,10 @@ Don-t-make-NetworkManager-D-Bus-activatable.patch systemd-Don-t-enable-NetworkManager-wait-online.service-s.patch Fix-iscsiadm-path.patch Export-_IO_stdin_used-symbol-in-NetworkManager.ver.patch +platform-split-processing-result-from-do_change_link.patch +platform-workaround-kernel-wrongly-returning-ENFILE-when-.patch +device-fix-spelling-in-logging.patch +device-add-hack-to-wait-after-changing-MAC-address.patch +shared-add-NM_MIN-NM_MAX-macros-to-replace-glib-s-MIN-MAX.patch +device-workaround-driver-issue-with-delayed-change-of-MAC.patch +device-wait-for-MAC-address-change-to-complete-before-set.patch diff --git a/debian/patches/shared-add-NM_MIN-NM_MAX-macros-to-replace-glib-s-MIN-MAX.patch b/debian/patches/shared-add-NM_MIN-NM_MAX-macros-to-replace-glib-s-MIN-MAX.patch new file mode 100644 index 0000000..d8a6c63 --- /dev/null +++ b/debian/patches/shared-add-NM_MIN-NM_MAX-macros-to-replace-glib-s-MIN-MAX.patch @@ -0,0 +1,65 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Mon, 5 Sep 2016 14:12:41 +0200 +Subject: 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(). */ |
