diff -pruN 1.26.2-1/debian/10-dns-resolved.conf 1.26.2-1ubuntu1/debian/10-dns-resolved.conf
--- 1.26.2-1/debian/10-dns-resolved.conf	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/10-dns-resolved.conf	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,5 @@
+[main]
+# We need to specify "dns=systemd-resolved" as for the time being our
+# /etc/resolv.conf points to resolvconf's generated file instead of
+# systemd-resolved's, so the auto-detection does not work.
+dns=systemd-resolved
diff -pruN 1.26.2-1/debian/10-globally-managed-devices.conf 1.26.2-1ubuntu1/debian/10-globally-managed-devices.conf
--- 1.26.2-1/debian/10-globally-managed-devices.conf	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/10-globally-managed-devices.conf	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,2 @@
+[keyfile]
+unmanaged-devices=*,except:type:wifi,except:type:gsm,except:type:cdma
diff -pruN 1.26.2-1/debian/20-connectivity-ubuntu.conf 1.26.2-1ubuntu1/debian/20-connectivity-ubuntu.conf
--- 1.26.2-1/debian/20-connectivity-ubuntu.conf	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/20-connectivity-ubuntu.conf	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,2 @@
+[connectivity]
+uri=http://connectivity-check.ubuntu.com./
diff -pruN 1.26.2-1/debian/changelog 1.26.2-1ubuntu1/debian/changelog
--- 1.26.2-1/debian/changelog	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/changelog	2020-08-31 09:09:40.000000000 +0000
@@ -1,3 +1,9 @@
+network-manager (1.26.2-1ubuntu1) groovy; urgency=medium
+
+  * Update to the current stable version
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 31 Aug 2020 11:09:40 +0200
+
 network-manager (1.26.2-1) unstable; urgency=medium
 
   * New upstream version 1.26.2
@@ -5,6 +11,46 @@ network-manager (1.26.2-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Wed, 19 Aug 2020 10:30:53 +0200
 
+network-manager (1.26.0-1ubuntu1) groovy; urgency=medium
+
+  * Resynchronize on Debian, remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet.
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems.
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+      + Read-system-connections-from-run.patch
+    - debian/tests/urfkill-integration - don't stop/start network manager
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 27 Jul 2020 17:09:03 +0200
+
 network-manager (1.26.0-1) unstable; urgency=medium
 
   * New upstream version 1.26.0
@@ -35,6 +81,14 @@ network-manager (1.25.90-1) unstable; ur
 
  -- Michael Biebl <biebl@debian.org>  Sun, 28 Jun 2020 19:29:43 +0200
 
+network-manager (1.24.2-1ubuntu2) groovy; urgency=medium
+
+  * debian/20-connectivity-ubuntu.conf: Add trailing dot to make
+    connectivity-check.ubuntu.com. absolute and reduce NXDOMAIN
+    warning noise, thanks MarchH (lp: #1880258)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 29 Jun 2020 16:20:07 +0200
+
 network-manager (1.24.2-1) unstable; urgency=medium
 
   [ Michael Biebl ]
@@ -46,6 +100,58 @@ network-manager (1.24.2-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Sun, 21 Jun 2020 13:44:56 +0200
 
+network-manager (1.24.0-1ubuntu2) groovy; urgency=medium
+
+  * debian/rules:
+    - the iptables binary is in /usr/sbin now, use the correct location in
+      the configure. Should fix the hotspot feature not working in GNOME
+      on upgraded systems which haven't been usrmerged.
+      (lp: #1870359)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Wed, 20 May 2020 12:03:07 +0200
+
+network-manager (1.24.0-1ubuntu1) groovy; urgency=medium
+
+  * Resynchronize on Debian, remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet.
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems.
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+      + Read-system-connections-from-run.patch
+    - debian/tests/urfkill-integration - don't stop/start network manager
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 19 May 2020 17:07:30 +0200
+
 network-manager (1.24.0-1) unstable; urgency=medium
 
   * New upstream version 1.24.0
@@ -64,6 +170,26 @@ network-manager (1.23.90-1) unstable; ur
 
  -- Michael Biebl <biebl@debian.org>  Sun, 12 Apr 2020 00:46:53 +0200
 
+network-manager (1.22.10-1ubuntu3) groovy; urgency=medium
+
+  * No-change rebuild to bump Groovy version number.
+
+ -- Dan Streetman <ddstreet@canonical.com>  Thu, 30 Apr 2020 07:47:49 -0400
+
+network-manager (1.22.10-1ubuntu2) focal; urgency=medium
+
+  * d/t/killswitches-no-urfkill
+    - Call udevadm settle before nmcli radio wifi
+      To make sure that change is updated. (LP: #1733321)
+
+ -- Seyeong Kim <seyeong.kim@canonical.com>  Mon, 20 Apr 2020 22:40:44 -0700
+
+network-manager (1.22.10-1ubuntu1) focal; urgency=medium
+
+  * Update to the current stable version, merging from Debian
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 13 Mar 2020 16:27:29 +0100
+
 network-manager (1.22.10-1) unstable; urgency=medium
 
   * New upstream version 1.22.10
@@ -125,6 +251,22 @@ network-manager (1.22.0-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Wed, 18 Dec 2019 19:05:33 +0100
 
+network-manager (1.20.8-1ubuntu2) focal; urgency=medium
+
+  * debian/rules:
+    - Omit building the uninstallable network-manager binary (depends on
+      wpasupplicant) on i386
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 10 Jan 2020 18:26:29 +0100
+
+network-manager (1.20.8-1ubuntu1) focal; urgency=medium
+
+  * New upstream version, merged from Debian
+  * debian/patches/git_wpa_sae.patch:
+    - removed, included in the new version
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 07 Jan 2020 17:00:01 +0100
+
 network-manager (1.20.8-1) unstable; urgency=medium
 
   * New upstream version 1.20.8
@@ -215,6 +357,107 @@ network-manager (1.18.0-2) experimental;
 
  -- Michael Biebl <biebl@debian.org>  Tue, 28 May 2019 22:27:17 +0200
 
+network-manager (1.18.0-1ubuntu6) eoan; urgency=medium
+
+  [ Till Kamppeter ]
+  * debian/tests/nm.py:
+    + Make activating an AP time out earlier than it otherwise would.
+    + Skip a call that is failing for IPv6 connections.
+
+  [ Iain Lane ]
+  * debian/tests/nm.py: Delete code skipped by the previous change, rather
+    than commenting it out and leaving it inactive in the source.
+
+  [ Sebastien Bacher ]
+  * Updated debian branch from eoan to master
+
+ -- Iain Lane <iain.lane@canonical.com>  Thu, 01 Aug 2019 13:17:35 +0100
+
+network-manager (1.18.0-1ubuntu5) eoan; urgency=medium
+
+  * Updated autopkg test nm.py for API changes in network-manager.
+
+  [ Mathieu Trudel-Lapierre ]
+  * debian/tests/control: fix test dependency to list gir1.2-nm-1.0 instead
+    of its old name gir1.2-networkmanager-1.0.
+
+ -- Till Kamppeter <till.kamppeter@canonical.com>  Tue, 25 Jun 2019 13:31:42 +0200
+
+network-manager (1.18.0-1ubuntu4) eoan; urgency=medium
+
+  * debian/tests/nm.py: give test_no_ap more time for wifi devices to start
+    as it may be necessary on ppc64el.
+
+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>  Wed, 29 May 2019 09:31:18 -0400
+
+network-manager (1.18.0-1ubuntu3) eoan; urgency=medium
+
+  * d/p/Read-system-connections-from-run.patch:
+    - remove, upstream addressed it in a different way/for different 
+      reasons in commit ce4dbd7daf.
+  * debian/network-manager-dev.install:
+    - update following the the recent binary changes
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 24 May 2019 11:26:30 +0200
+
+network-manager (1.18.0-1ubuntu2) eoan; urgency=medium
+
+  * debian/control, debian/lib*.install, debian/rules:
+    - remove the deprecated libnm-glib/vpn/util libraries
+  * debian/patches/series:
+    - restore Read-system-connections-from-run.patch which had been
+      dropped by error.
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 24 May 2019 00:07:31 +0200
+
+network-manager (1.18.0-1ubuntu1) eoan; urgency=medium
+
+  * Update to 1.18, merge on Debian, new version includes nwe support for 
+    policy routing rules and for VLAN filtering for Linux bridge.
+  * Remaining Ubuntu changes
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet.
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems.
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+      + Read-system-connections-from-run.patch
+    - debian/tests/urfkill-integration - don't stop/start network manager
+    - Revert "Add Conflicts to network-manager-dev against deprecated libraries"
+      This reverts commit b4acc5e03e2b821e1cccc69529bb70826c741942.  We're still
+      building libnm-glib for now, so these packages have a use in Ubuntu.
+  * Removed delta, not needed anymore
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 10 May 2019 15:07:08 +0200
+
 network-manager (1.18.0-1) experimental; urgency=medium
 
   * New upstream version 1.18.0
@@ -258,6 +501,51 @@ network-manager (1.14.6-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Tue, 26 Feb 2019 19:33:53 +0100
 
+network-manager (1.16.0-0ubuntu2) disco; urgency=medium
+
+  * debian/patches/git_ifupdown_iterator.patch:
+    - ifupdown: fix connection iterator, should fix a segfault in the
+      corresponding plugin (lp: #1815742)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 02 Apr 2019 17:53:26 +0200
+
+network-manager (1.16.0-0ubuntu1) disco; urgency=medium
+
+  * New upstream version
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 19 Mar 2019 16:23:09 +0100
+
+network-manager (1.15.91-0Ubuntu1) disco; urgency=medium
+
+  * New upstream version
+  * remove patches included in the new version
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 12 Mar 2019 15:23:26 +0100
+
+network-manager (1.15.2-0ubuntu2) disco; urgency=medium
+
+  * debian/patches/git_ifupdown_segfault.patch:
+    - 'settings/ifupdown: fix ifupdown plugin after merging eni_ifaces and 
+       connections hashes' (lp: #1815742)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 18 Feb 2019 17:06:17 +0100
+
+network-manager (1.15.2-0ubuntu1) disco; urgency=medium
+
+  * Update to the current serie, resynchronize with Debian
+  * debian/libnm0.symbols:
+    - updated for the new version
+  * debian/patches
+    - removed the changes that are included in the new version
+  * debian/patches/git_team_structure.patch:
+    - backport upstream change 'fix team link-watcher struct layout',
+      the tests/build failed on i386
+  * debian/rules:
+    - strip '-Wl,-Bsymbolic-functions' from LDFLAGS otherwise the
+      tests fails on 'cannot register existing type 'NMAgentManagerError''
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 25 Jan 2019 11:31:56 +0100
+
 network-manager (1.14.4-4) unstable; urgency=medium
 
   * Move D-Bus policy files to /usr/share/dbus-1/system.d/
@@ -341,6 +629,91 @@ network-manager (1.13.90-1) experimental
 
  -- Michael Biebl <biebl@debian.org>  Sat, 08 Sep 2018 18:23:20 +0200
 
+network-manager (1.12.6-0ubuntu4) disco; urgency=medium
+
+  * No-change rebuild for readline soname change.
+
+ -- Matthias Klose <doko@ubuntu.com>  Mon, 14 Jan 2019 20:02:35 +0000
+
+network-manager (1.12.6-0ubuntu3) disco; urgency=medium
+
+  * debian/tests/nm.py: Make assert_iface_down() not check the interface's
+    state. We call nmclient.deactivate_connection() to terminate connections
+    that the testsuite sets up, and according to upstream this is not
+    guaranteed to do anything in particular to the link state. It seems that
+    dnsmasq 2.80 somehow alters the previous assumption that it would be
+    'state DOWN', so the implementation detail we were checking previously no
+    longer holds. The testsuite does still check that the IPs are removed from
+    the interface, which is logically what we want anyway. (LP: #1805857)
+  * debian/control: Fix Vcs-Git
+
+ -- Iain Lane <iain.lane@canonical.com>  Wed, 19 Dec 2018 13:12:58 +0000
+
+network-manager (1.12.6-0ubuntu2) disco; urgency=medium
+
+  [ Robie Basak ]
+  * debian/tests:
+    - Make dep8 nm test directly invokable
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 10 Dec 2018 22:03:01 +0100
+
+network-manager (1.12.6-0ubuntu1) disco; urgency=medium
+
+  * New upstream version
+    - Fix a vulnerability in the internal DHCPv6 client (CVE-2018-15688).
+  * debian/patches/git_mac_change.patch:
+    - backported a regression fix from upstream git
+
+  [ Alfonso Sanchez-Beato ]
+  * Import some WoWLAN patches from the newer stable serie (LP: #1781597)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 10 Dec 2018 18:50:07 +0100
+
+network-manager (1.12.4-1ubuntu1) cosmic; urgency=medium
+
+  * Merge with Debian (LP: #1795704). Remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet.
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems.
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+      + Read-system-connections-from-run.patch
+    - debian/tests/urfkill-integration - don't stop/start network manager
+  * Revert "Add Conflicts to network-manager-dev against deprecated libraries"
+    This reverts commit b4acc5e03e2b821e1cccc69529bb70826c741942.  We're still
+    building libnm-glib for now, so these packages have a use in Ubuntu.
+
+ -- Iain Lane <iain.lane@canonical.com>  Wed, 03 Oct 2018 10:03:10 +0100
+
 network-manager (1.12.4-1) unstable; urgency=medium
 
   * New upstream version 1.12.4
@@ -371,6 +744,64 @@ network-manager (1.12.2-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Wed, 25 Jul 2018 13:35:31 +0200
 
+network-manager (1.12.2-0ubuntu5) cosmic; urgency=medium
+
+  * debian/tests/nm: Add the required `gi.require_version()` calls - thanks to
+    the autopkgtests for noticing this.
+  * debian/tests/control: The nm tests need dnsmasq-base and isc-dhcp-client
+    too.
+
+ -- Iain Lane <iain@orangesquash.org.uk>  Mon, 24 Sep 2018 10:17:30 +0100
+
+network-manager (1.12.2-0ubuntu4) cosmic; urgency=medium
+
+  Cherry-pick fixes from debian:
+  * Fix compile error due to NM_AVAILABLE_IN_1_12_2 macro in n-m-applet
+  * Apply patch from upstream to fix FTBFS with GLib 2.57
+
+ -- Didier Roche <didrocks@ubuntu.com>  Mon, 10 Sep 2018 11:36:35 +0200
+
+network-manager (1.12.2-0ubuntu3) cosmic; urgency=medium
+
+  * debian/rules:
+    - use --with-libnm-glib, the default reversed since that's a legacy
+      library but we still need it for unity-control-center
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 24 Aug 2018 11:00:09 +0200
+
+network-manager (1.12.2-0ubuntu2) cosmic; urgency=medium
+
+  * debian/patches/git-newglib-test.patch:
+    - backport upstream commit to fix the tests with the new glib 
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 24 Aug 2018 10:44:12 +0200
+
+network-manager (1.12.2-0ubuntu1) cosmic; urgency=medium
+
+  * New upstream version
+  * d/p/libnm-register-empty-NMClient-and-NetworkManager-when-loa.patch,
+    d/p/e91f1a7d2a6b8400b6b331d5b72287dcb5164a39.patch,
+    d/p/git_thunderbolt_connect.patch:
+    - removed, those changes are in the new version
+  * Backport Debian changes
+  * Update symbols file for libnm0
+  * Enable iwd support
+  * Drop version requirements when oldstable ships a newer version
+  * Drop dh_strip override, the dbgsym migration is done
+  * Rebase patches
+  * Make sure the example server.conf is actually installed
+  * Update install path for plugins, it now includes a version number
+  * Drop libnl3 build dependency.
+    Upstream has copied the code directly from libnl3 for the few functions it
+    needs with a few small modifications.
+  * Drop libiw build dependency.
+    Hasn't been needed for a long time and was simply a left over from older
+    releases.
+  * Bump Standards-Version to 4.1.5
+  * Fix compile error due to NM_AVAILABLE_IN_1_12_2 macro (Closes: #905372)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 24 Aug 2018 09:27:39 +0200
+
 network-manager (1.12.0-5) unstable; urgency=medium
 
   * manager: accept non-null device for VPN activations (Closes: #903109)
@@ -454,6 +885,75 @@ network-manager (1.11.3-1) experimental;
 
  -- Michael Biebl <biebl@debian.org>  Mon, 23 Apr 2018 23:35:35 +0200
 
+network-manager (1.10.8-1ubuntu4) cosmic; urgency=medium
+
+  * debian/10-globally-managed-devices.conf: adjust exception for wwan to
+    specify cdma and gsm, since those are the actual types handled by NM/MM.
+    (LP: #1780606)
+
+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>  Tue, 10 Jul 2018 08:17:11 -0400
+
+network-manager (1.10.8-1ubuntu3) cosmic; urgency=medium
+
+  * Revert the changes to remove the nmclient bindings, those are needed
+    to build nm-applet until the legacy binaries can be removed, which
+    requires unity-control-center to be updated to use the new library.
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Wed, 04 Jul 2018 15:30:19 +0200
+
+network-manager (1.10.8-1ubuntu2) cosmic; urgency=medium
+
+  * debian/patches/git_thunderbolt_connect.patch:
+    - enable host to host connection through thunderbolt
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 25 May 2018 16:54:48 +0200
+
+network-manager (1.10.8-1ubuntu1) cosmic; urgency=medium
+
+  * Merge with Debian (LP: #1758331). Remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet. (LP: #1676547)
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems. (LP: #1681513)
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch
+      + Read-system-connections-from-run.patch
+      + e91f1a7d2a6b8400b6b331d5b72287dcb5164a39.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+    - debian/tests/urfkill-integration - don't stop/start network manager
+  * Keep libnm-glib/libnm-util a bit longer since unity-control-center
+    still needs them. See bug 1744619
+
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Fri, 11 May 2018 19:52:40 -0400
+
 network-manager (1.10.8-1) unstable; urgency=medium
 
   * New upstream version 1.10.8
@@ -469,6 +969,52 @@ network-manager (1.10.6-3) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Wed, 18 Apr 2018 19:40:01 +0200
 
+network-manager (1.10.6-2ubuntu1) bionic; urgency=medium
+
+  * Merge with Debian (LP: #1758331). Remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet. (LP: #1676547)
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems. (LP: #1681513)
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch
+      + Read-system-connections-from-run.patch
+      + e91f1a7d2a6b8400b6b331d5b72287dcb5164a39.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+    - debian/tests/urfkill-integration - don't stop/start network manager
+  * Dropped patches applied in new release:
+    - settings-preserve-agent-owned-secrets-on-connection-updat.patch
+
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Mon, 26 Mar 2018 09:21:12 -0400
+
 network-manager (1.10.6-2) unstable; urgency=medium
 
   * Update Vcs-* to point to https://salsa.debian.org
@@ -482,6 +1028,82 @@ network-manager (1.10.6-1) unstable; urg
 
  -- Michael Biebl <biebl@debian.org>  Tue, 13 Mar 2018 01:47:52 +0100
 
+network-manager (1.10.4-1ubuntu3) bionic; urgency=medium
+
+  * Cherry-pick a partial patch from 1.11 branch, to stop agressively
+    setting route_only flag on nameservers in the systemd-resolved dns
+    plugin. LP: #1751797
+
+ -- Dimitri John Ledkov <xnox@ubuntu.com>  Thu, 15 Mar 2018 15:24:01 +0000
+
+network-manager (1.10.4-1ubuntu2) bionic; urgency=medium
+
+  [ Bryan Quigley ]
+  * debian/tests/urfkill-integration - don't stop/start network manager
+
+  [ Jeremy Bicha ]
+  * Cherry-pick patch from 1.10 branch to fix double prompt for wifi password
+    on Kubuntu (LP: #1572244)
+
+ -- Bryan Quigley <bryan.quigley@canonical.com>  Fri, 23 Feb 2018 13:52:48 -0500
+
+network-manager (1.10.4-1ubuntu1) bionic; urgency=medium
+
+  * Merge with Debian (LP: #1734586). Remaining changes:
+    - Use systemd-resolved instead of dnsmasq
+    - debian/control:
+      + Depend on isc-dhcp-client instead of recommends
+      + Recommend network-manager-pptp
+      + Suggest avahi-autoipd for IPv4LL support
+    - debian/rules, debian/network-manager.postinst:
+      + Don't restart NetworkManager on upgrade but recommend restarting
+        the computer
+    - debian/rules, debian/network-manager.postinst:
+      + Don't install sysvinit scripts or migrate from sysvinit
+    - debian/network-manager.postinst:
+      + Don't add the netdev group.
+      + drop in an empty override file for NetworkManager to manage all
+        devices for upgrade from any version, as long as there is no
+        netplan configuration yet. (LP: #1676547)
+    - debian/network-manager.maintscript
+      + Remove /etc/dbus-1/system.d/nm-ofono.conf
+    - debian/default-wifi-powersave-on.conf, debian/rules:
+      + Install a config file to enable WiFi powersave
+    - Enable build tests
+    - Add autopkgtests
+    - debian/source_network-manager.py, debian/network-manager.install,
+      debian/network-manager.links: Add apport hook
+    - Add network-manager-config-connectivity-ubuntu package
+    - NetworkManager.conf: disable MAC randomization feature. There is no
+      easy way for desktop users to disable this feature yet. And there are
+      reports that it doesn't work well with some systems. (LP: #1681513)
+    - Update Vcs links to point to Ubuntu branch
+    - Add patches. See patch descriptions for more details:
+      + Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+      + Update-dnsmasq-parameters.patch
+      + Disable-general-with-expect.patch
+      + libnm-Check-self-still-NMManager-or-not.patch
+      + dns-manager-don-t-merge-split-DNS-search-domains.patch
+      + Read-system-connections-from-run.patch
+  * Disable dns-manager-don-t-merge-split-DNS-search-domains.patch:
+    This patch needs to be updated for the new release but so far, no
+    one that understands the issue and patch have worked to update it.
+    After waiting for several weeks, we thought it was more important
+    to get this major version update into bionic now.
+  * Dropped patches applied in new release:
+    - connectivity-allow-override.patch
+    - nm1.10-connectivity-check-api.patch
+    - fix-resolved-detection.patch
+  * Other dropped changes:
+    - debian/control, debian/rules:
+      + Disable team support since it's in universe (LP: #1392012)
+    - Obsolete Ubuntu Phone related patches:
+      + Ignore-p2p0-wifi-devices-from-android.patch
+      + Ignore-rmnet_usbX-devices.patch'
+      + Track-killswitch-change-signals-from-urfkill.patch
+
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Fri, 09 Feb 2018 12:21:37 -0500
+
 network-manager (1.10.4-1) unstable; urgency=medium
 
   [ Laurent Bigonville ]
diff -pruN 1.26.2-1/debian/control 1.26.2-1ubuntu1/debian/control
--- 1.26.2-1/debian/control	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/control	2020-08-31 09:09:40.000000000 +0000
@@ -1,7 +1,8 @@
 Source: network-manager
 Section: net
 Priority: optional
-Maintainer: Utopia Maintenance Team <pkg-utopia-maintainers@lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Utopia Maintenance Team <pkg-utopia-maintainers@lists.alioth.debian.org>
 Uploaders: Michael Biebl <biebl@debian.org>,
  Sjoerd Simons <sjoerd@debian.org>,
  Aron Xu <aron@debian.org>
@@ -41,8 +42,10 @@ Build-Depends: debhelper-compat (= 13),
                python3-dbus <!nocheck>
 Standards-Version: 4.5.0
 Rules-Requires-Root: no
-Vcs-Git: https://salsa.debian.org/utopia-team/network-manager.git
-Vcs-Browser: https://salsa.debian.org/utopia-team/network-manager
+XS-Debian-Vcs-Git: https://salsa.debian.org/utopia-team/network-manager.git
+XS-Debian-Vcs-Browser: https://salsa.debian.org/utopia-team/network-manager
+Vcs-Git: https://git.launchpad.net/network-manager
+Vcs-Browser: https://git.launchpad.net/network-manager
 Homepage: https://wiki.gnome.org/Projects/NetworkManager
 
 Package: network-manager
@@ -61,8 +64,10 @@ Recommends: ppp,
             dnsmasq-base,
             iptables,
             modemmanager,
+            network-manager-pptp,
             crda,
-Suggests: libteam-utils,
+Suggests: avahi-autoipd,
+          libteam-utils,
           isc-dhcp-client,
 Breaks: ${misc:Breaks}
 Description: network management framework (daemon and userspace tools)
@@ -76,6 +81,8 @@ Description: network management framewor
  interact with NetworkManager.
  .
  Optional dependencies:
+  * avahi-autoipd: Used for IPv4LL, a protocol for automatic Link-Local IP
+    address configuration.
   * ppp: Required for establishing dial-up connections (e.g. via GSM).
   * dnsmasq-base/iptables: Required for creating Ad-hoc connections and
     connection sharing.
@@ -165,3 +172,21 @@ Description: NetworkManager configuratio
  No user data is transmitted in the connectivity checks, but merely contacting
  the Debian connectivity check servers reveals that the user is running a
  Debian(-based) operating system with NetworkManager.
+
+Package: network-manager-config-connectivity-ubuntu
+Architecture: all
+Multi-Arch: foreign
+Depends: ${misc:Depends},
+         network-manager (>= ${source:Version})
+Description: NetworkManager configuration to enable connectivity checking
+ This package contains a configuration file which enables NetworkManager's
+ connectivity checking functionality.
+ .
+ NetworkManager will try to connect to an Ubuntu server to determine the
+ connection status.
+ .
+ This is particularly useful for captive portal detection.
+ .
+ No user data is transmitted in the connectivity checks, but merely contacting
+ the Ubuntu connectivity check servers reveals that the user is running an
+ Ubuntu(-based) operating system with NetworkManager.
diff -pruN 1.26.2-1/debian/default-wifi-powersave-on.conf 1.26.2-1ubuntu1/debian/default-wifi-powersave-on.conf
--- 1.26.2-1/debian/default-wifi-powersave-on.conf	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/default-wifi-powersave-on.conf	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,2 @@
+[connection]
+wifi.powersave = 3
diff -pruN 1.26.2-1/debian/gbp.conf 1.26.2-1ubuntu1/debian/gbp.conf
--- 1.26.2-1/debian/gbp.conf	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/gbp.conf	2020-08-31 09:09:40.000000000 +0000
@@ -1,5 +1,6 @@
 [DEFAULT]
 pristine-tar = True
 patch-numbers = False
-debian-branch = debian/master
+debian-branch = ubuntu/master
+debian-tag = ubuntu/%(version)s
 upstream-branch = upstream/latest
diff -pruN 1.26.2-1/debian/NetworkManager.conf 1.26.2-1ubuntu1/debian/NetworkManager.conf
--- 1.26.2-1/debian/NetworkManager.conf	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/NetworkManager.conf	2020-08-31 09:09:40.000000000 +0000
@@ -3,3 +3,6 @@ plugins=ifupdown,keyfile
 
 [ifupdown]
 managed=false
+
+[device]
+wifi.scan-rand-mac-address=no
diff -pruN 1.26.2-1/debian/network-manager-config-connectivity-ubuntu.install 1.26.2-1ubuntu1/debian/network-manager-config-connectivity-ubuntu.install
--- 1.26.2-1/debian/network-manager-config-connectivity-ubuntu.install	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/network-manager-config-connectivity-ubuntu.install	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1 @@
+debian/20-connectivity-ubuntu.conf usr/lib/NetworkManager/conf.d/
diff -pruN 1.26.2-1/debian/network-manager-config-connectivity-ubuntu.postinst 1.26.2-1ubuntu1/debian/network-manager-config-connectivity-ubuntu.postinst
--- 1.26.2-1/debian/network-manager-config-connectivity-ubuntu.postinst	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/network-manager-config-connectivity-ubuntu.postinst	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+
+if [ "$1" = configure ]; then
+    invoke-rc.d network-manager force-reload || true
+fi
+
+#DEBHELPER#
diff -pruN 1.26.2-1/debian/network-manager.install 1.26.2-1ubuntu1/debian/network-manager.install
--- 1.26.2-1/debian/network-manager.install	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/network-manager.install	2020-08-31 09:09:40.000000000 +0000
@@ -24,5 +24,7 @@ lib/systemd/system/NetworkManager-dispat
 lib/systemd/system/NetworkManager-wait-online.service
 debian/NetworkManager.conf etc/NetworkManager/
 debian/org.freedesktop.NetworkManager.pkla var/lib/polkit-1/localauthority/10-vendor.d/
+debian/10-*.conf usr/lib/NetworkManager/conf.d/
 debian/60-network-manager.rules usr/share/polkit-1/rules.d/
 debian/01-ifupdown etc/NetworkManager/dispatcher.d/
+debian/source_network-manager.py /usr/share/apport/package-hooks/
diff -pruN 1.26.2-1/debian/network-manager.links 1.26.2-1ubuntu1/debian/network-manager.links
--- 1.26.2-1/debian/network-manager.links	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/network-manager.links	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1 @@
+/usr/share/apport/package-hooks/source_network-manager.py /usr/share/apport/package-hooks/source_network-manager-applet.py
diff -pruN 1.26.2-1/debian/network-manager.postinst 1.26.2-1ubuntu1/debian/network-manager.postinst
--- 1.26.2-1/debian/network-manager.postinst	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/network-manager.postinst	2020-08-31 09:09:40.000000000 +0000
@@ -20,9 +20,16 @@ set -e
 
 case "$1" in
     configure)
-        # Create netdev group. Members of group netdev get access to the PolicyKit action
-        # org.freedesktop.NetworkManager.settings.modify.system without prior authentication
-        addgroup --quiet --system netdev
+        # request a reboot (NM tears down interfaces on restart
+        # which is not the way we want to go)
+        [ -x /usr/share/update-notifier/notify-reboot-required ] && \
+            /usr/share/update-notifier/notify-reboot-required
+
+        update-rc.d -f NetworkManager remove >/dev/null
+
+        if [ -x "/etc/init.d/dbus" ]; then
+            invoke-rc.d dbus force-reload || true
+        fi
 
         # This directory can contain sensitive data and should not be world-readable
         chmod 0700 /var/lib/NetworkManager
@@ -48,6 +55,15 @@ case "$1" in
             fi
         fi
 
+	if dpkg --compare-versions "$2" le-nl "9999"; then
+		mkdir -p /etc/NetworkManager/conf.d || true
+		# for old versions, override the global config with a null config,
+		# but only if the netplan config has not been modified by an user.
+		if find /etc/netplan -name "*.yaml" | wc -l | grep -qc 0; then
+			touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
+		fi
+	fi
+
         if dpkg --compare-versions "$2" lt-nl "1.20.4-2"; then
             if [ -f /var/lib/NetworkManager/secret_key ]; then
                 chmod 0600 /var/lib/NetworkManager/secret_key
diff -pruN 1.26.2-1/debian/patches/dns-manager-don-t-merge-split-DNS-search-domains.patch 1.26.2-1ubuntu1/debian/patches/dns-manager-don-t-merge-split-DNS-search-domains.patch
--- 1.26.2-1/debian/patches/dns-manager-don-t-merge-split-DNS-search-domains.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/dns-manager-don-t-merge-split-DNS-search-domains.patch	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,88 @@
+From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
+Date: Wed, 15 Jun 2016 16:07:27 +0300
+Subject: dns-manager: don't merge split-DNS search domains
+
+Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/1592721
+---
+ src/dns/nm-dns-manager.c | 36 ++++++++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+Index: b/src/dns/nm-dns-manager.c
+===================================================================
+--- a/src/dns/nm-dns-manager.c
++++ b/src/dns/nm-dns-manager.c
+@@ -295,7 +295,7 @@
+ }
+ 
+ static void
+-merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src)
++merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src, gboolean never_default)
+ {
+ 	guint32 num, num_domains, num_searches, i;
+ 
+@@ -308,13 +308,14 @@
+ 	num_domains = nm_ip4_config_get_num_domains (src);
+ 	num_searches = nm_ip4_config_get_num_searches (src);
+ 
+-	for (i = 0; i < num_searches; i++) {
+-		const char *search;
+-
+-		search = nm_ip4_config_get_search (src, i);
+-		if (!domain_is_valid (search, FALSE))
+-			continue;
+-		add_string_item (rc->searches, search);
++	if (!never_default) {
++		for (i = 0; i < num_searches; i++) {
++			const char *search;
++			search = nm_ip4_config_get_search (src, i);
++			if (!domain_is_valid (search, FALSE))
++				continue;
++			add_string_item (rc->searches, search);
++		}
+ 	}
+ 
+ 	if (num_domains > 1 || !num_searches) {
+@@ -351,7 +352,7 @@
+ }
+ 
+ static void
+-merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface)
++merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface, gboolean never_default)
+ {
+ 	guint32 num, num_domains, num_searches, i;
+ 
+@@ -378,13 +379,14 @@
+ 	num_domains = nm_ip6_config_get_num_domains (src);
+ 	num_searches = nm_ip6_config_get_num_searches (src);
+ 
+-	for (i = 0; i < num_searches; i++) {
+-		const char *search;
+-
+-		search = nm_ip6_config_get_search (src, i);
+-		if (!domain_is_valid (search, FALSE))
+-			continue;
+-		add_string_item (rc->searches, search);
++	if (!never_default) {
++		for (i = 0; i < num_searches; i++) {
++			const char *search;
++			search = nm_ip6_config_get_search (src, i);
++			if (!domain_is_valid (search, FALSE))
++				continue;
++			add_string_item (rc->searches, search);
++		}
+ 	}
+ 
+ 	if (num_domains > 1 || !num_searches) {
+@@ -412,9 +414,9 @@
+                           NMDnsIPConfigData *data)
+ {
+ 	if (NM_IS_IP4_CONFIG (data->config))
+-		merge_one_ip4_config (rc, (NMIP4Config *) data->config);
++		merge_one_ip4_config (rc, (NMIP4Config *) data->config, nm_ip4_config_get_never_default (data->config));
+ 	else if (NM_IS_IP6_CONFIG (data->config))
+-		merge_one_ip6_config (rc, (NMIP6Config *) data->config, data->iface);
++		merge_one_ip6_config (rc, (NMIP6Config *) data->config, data->iface, nm_ip4_config_get_never_default (data->config));
+ 	else
+ 		g_return_if_reached ();
+ }
diff -pruN 1.26.2-1/debian/patches/gitlab_connection_ready.patch 1.26.2-1ubuntu1/debian/patches/gitlab_connection_ready.patch
--- 1.26.2-1/debian/patches/gitlab_connection_ready.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/gitlab_connection_ready.patch	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,115 @@
+
+From 1043189ef6bd12475304bbe87f4f8daaf67402ec Mon Sep 17 00:00:00 2001
+From: Thomas Haller <thaller@redhat.com>
+Date: Fri, 31 Jan 2020 00:54:46 +0100
+Subject: [PATCH 2/2] libnm: hide NMActiveConnection until NMRemoteConnection
+ is ready
+
+Generally, libnm's NMClient cache only wants to expose NMObjects that
+are fully initalized. Most objects don't require anything special,
+except NMRemoteConnection waits for the GetSettings() call to complete.
+
+NMObjects reference each other. For example, NMActiveConnection
+references NMDevice and NMRemoteConnection. There is a desire that an
+object is only ready, if the objects that it references are ready too.
+In practice that is not done, because usually every objects references
+other objects, that means all objects would be declared as non-ready
+until they are all ready at the same time. Only NMRemoteConnection
+implements is_ready() function. All other objects are declared ready
+as they appear. This is also done this way, to cope with cycles where
+objects reference each other. In practice, such cycles should not be
+exposed by NetworkManager. However, libnm should be robust against that.
+
+This has the undesired effect that when you call AddAndActivate(), then
+the NMActiveConnection might already be ready while its
+NMRemoteConnection isn't. That means, ac.get_connection() will
+initially return NULL, until the remote connection becomes ready.
+Also add a special handling that NMActiveConnection waits for their
+NMRemoteConnection to be ready, before being ready itself.
+---
+ libnm/nm-active-connection.c | 29 +++++++++++++++++++++++++++++
+ libnm/nm-client.c            |  8 ++++++++
+ libnm/nm-libnm-utils.h       |  2 ++
+ 3 files changed, 39 insertions(+)
+
+diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c
+index aa8504e61d..ade2edbe73 100644
+--- a/libnm/nm-active-connection.c
++++ b/libnm/nm-active-connection.c
+@@ -425,6 +425,33 @@ _nm_active_connection_state_changed_commit (NMActiveConnection *self,
+ 	                                        _notify_event_state_changed,
+ 	                                        g_object_ref (self));
+ }
++/*****************************************************************************/
++
++static gboolean
++is_ready (NMObject *nmobj)
++{
++	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (nmobj);
++
++	/* Usually, we don't want to expose our NMObject instances until they are fully initialized.
++	 * For NMRemoteSetting this means to wait until GetSettings() returns.
++	 *
++	 * Note that most object types reference each other (directly or indirectly). E.g. the
++	 * NMActiveConnection refers to the NMRemoteConnection and the NMDevice instance. So,
++	 * we don't want to hide them too long, otherwise basically the entire set of objects
++	 * will be hidden until they are all initialized. So, usually, when a NMObject references
++	 * objects that are not yet initialized, that reference will just be NULL but the object
++	 * will be considered ready already.
++	 *
++	 * For NMActiveConnection referencing a NMRemoteConnection don't do that. Here we wait for the
++	 * NMRemoteConnection to be ready as well. This is somewhat arbitrary special casing, but
++	 * the effect is that when nm_client_add_and_activate*() returns, the NMActiveConnection already
++	 * references a initialized NMRemoteConnection.
++	 */
++	if (!nml_dbus_property_o_is_ready_fully (&priv->property_o[PROPERTY_O_IDX_CONNECTION]))
++		return FALSE;
++
++	return NM_OBJECT_CLASS (nm_active_connection_parent_class)->is_ready (nmobj);
++}
+ 
+ /*****************************************************************************/
+ 
+@@ -550,6 +577,8 @@ nm_active_connection_class_init (NMActiveConnectionClass *klass)
+ 	object_class->get_property = get_property;
+ 	object_class->finalize     = finalize;
+ 
++	nm_object_class->is_ready = is_ready;
++
+ 	_NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT (nm_object_class, NMActiveConnection);
+ 
+ 	_NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N (nm_object_class, NMActiveConnectionPrivate, property_o);
+diff --git a/libnm/nm-client.c b/libnm/nm-client.c
+index 154ad1c992..a93a81c353 100644
+--- a/libnm/nm-client.c
++++ b/libnm/nm-client.c
+@@ -1594,6 +1594,14 @@ nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o)
+ 	       || !pr_o->owner_dbobj;
+ }
+ 
++gboolean
++nml_dbus_property_o_is_ready_fully (const NMLDBusPropertyO *pr_o)
++{
++	return    !pr_o->owner_dbobj
++	       || !pr_o->obj_watcher
++	       || pr_o->nmobj;
++}
++
+ static void
+ nml_dbus_property_o_notify_changed (NMLDBusPropertyO *pr_o,
+                                     NMClient *self)
+diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h
+index f2affc5f62..28c9c1164c 100644
+--- a/libnm/nm-libnm-utils.h
++++ b/libnm/nm-libnm-utils.h
+@@ -260,6 +260,8 @@ gpointer nml_dbus_property_o_get_obj (NMLDBusPropertyO *pr_o);
+ 
+ gboolean nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o);
+ 
++gboolean nml_dbus_property_o_is_ready_fully (const NMLDBusPropertyO *pr_o);
++
+ void nml_dbus_property_o_clear (NMLDBusPropertyO *pr_o,
+                                 NMClient *client);
+ 
+-- 
+2.24.1
diff -pruN 1.26.2-1/debian/patches/Import-some-missing-WoWLAN-patches.patch 1.26.2-1ubuntu1/debian/patches/Import-some-missing-WoWLAN-patches.patch
--- 1.26.2-1/debian/patches/Import-some-missing-WoWLAN-patches.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/Import-some-missing-WoWLAN-patches.patch	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,355 @@
+From: =?utf-8?q?Alfonso_S=C3=A1nchez-Beato?=
+ <alfonso.sanchez-beato@canonical.com>
+Date: Wed, 5 Dec 2018 17:28:15 +0100
+Subject: Import some missing WoWLAN patches from 1.14:
+
+ac1302793 platform: add methods to retrieve current WoWLAN state
+c6e40215e devices: restore past WoWLAN when disconnecting wifi
+a3289400d wifi: ensure wake-on-wlan restore only acts once
+---
+ src/devices/wifi/nm-device-wifi.c      | 48 +++++++++++++++++++++++---
+ src/platform/nm-linux-platform.c       |  8 +++++
+ src/platform/nm-platform.c             | 10 ++++++
+ src/platform/nm-platform.h             |  2 ++
+ src/platform/wifi/wifi-utils-nl80211.c | 62 ++++++++++++++++++++++++++++++++--
+ src/platform/wifi/wifi-utils-private.h |  3 ++
+ src/platform/wifi/wifi-utils.c         | 10 ++++++
+ src/platform/wifi/wifi-utils.h         |  2 ++
+ 8 files changed, 137 insertions(+), 8 deletions(-)
+
+diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
+index 0dd6fa7..3008ada 100644
+--- a/src/devices/wifi/nm-device-wifi.c
++++ b/src/devices/wifi/nm-device-wifi.c
+@@ -121,6 +121,8 @@ typedef struct {
+ 	gint32 hw_addr_scan_expire;
+ 
+ 	guint             wps_timeout_id;
++
++	NMSettingWirelessWakeOnWLan wowlan_restore;
+ } NMDeviceWifiPrivate;
+ 
+ struct _NMDeviceWifi
+@@ -508,6 +510,22 @@ remove_all_aps (NMDeviceWifi *self)
+ 	nm_device_recheck_available_connections (NM_DEVICE (self));
+ }
+ 
++static gboolean
++wake_on_wlan_restore (NMDeviceWifi *self)
++{
++	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
++	NMSettingWirelessWakeOnWLan w;
++
++	w = priv->wowlan_restore;
++	if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE)
++		return TRUE;
++
++	priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
++	return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET,
++	                                          nm_device_get_ifindex (NM_DEVICE (self)),
++	                                          w);
++}
++
+ static void
+ deactivate (NMDevice *device)
+ {
+@@ -524,6 +542,9 @@ deactivate (NMDevice *device)
+ 
+ 	set_current_ap (self, NULL, TRUE);
+ 
++	if (!wake_on_wlan_restore (self))
++		_LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot unconfigure WoWLAN.");
++
+ 	/* Clear any critical protocol notification in the Wi-Fi stack */
+ 	nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE);
+ 
+@@ -2426,6 +2447,7 @@ error:
+ static gboolean
+ wake_on_wlan_enable (NMDeviceWifi *self)
+ {
++	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ 	NMSettingWirelessWakeOnWLan wowl;
+ 	NMSettingWireless *s_wireless;
+ 	gs_free char *value = NULL;
+@@ -2461,8 +2483,19 @@ wake_on_wlan_enable (NMDeviceWifi *self)
+ 			goto found;
+ 	}
+ 	wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
++
+ found:
+-	return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), wowl);
++	if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) {
++		priv->wowlan_restore = wowl;
++		return TRUE;
++	}
++
++	priv->wowlan_restore = nm_platform_wifi_get_wake_on_wlan (NM_PLATFORM_GET,
++	                                                          nm_device_get_ifindex (NM_DEVICE (self)));
++
++	return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET,
++	                                          nm_device_get_ifindex (NM_DEVICE (self)),
++	                                          wowl);
+ }
+ 
+ static NMActStageReturn
+@@ -2659,8 +2692,6 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
+ 	s_wireless = nm_connection_get_setting_wireless (connection);
+ 	g_assert (s_wireless);
+ 
+-	wake_on_wlan_enable (self);
+-
+ 	/* If we need secrets, get them */
+ 	setting_name = nm_connection_need_secrets (connection, NULL);
+ 	if (setting_name) {
+@@ -2677,6 +2708,9 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
+ 		goto out;
+ 	}
+ 
++	if (!wake_on_wlan_enable (self))
++		_LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN.");
++
+ 	/* have secrets, or no secrets required */
+ 	if (nm_connection_get_setting_wireless_security (connection)) {
+ 		_LOGI (LOGD_DEVICE | LOGD_WIFI,
+@@ -2727,8 +2761,10 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
+ 	ret = NM_ACT_STAGE_RETURN_POSTPONE;
+ 
+ out:
+-	if (ret == NM_ACT_STAGE_RETURN_FAILURE)
++	if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
+ 		cleanup_association_attempt (self, TRUE);
++		wake_on_wlan_restore (self);
++	}
+ 
+ 	if (config) {
+ 		/* Supplicant interface object refs the config; we no longer care about
+@@ -3134,7 +3170,8 @@ reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_n
+ 
+ 	_LOGD (LOGD_DEVICE, "reapplying wireless settings");
+ 
+-	wake_on_wlan_enable (self);
++	if (!wake_on_wlan_enable (self))
++		_LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN.");
+ }
+ 
+ /*****************************************************************************/
+@@ -3207,6 +3244,7 @@ nm_device_wifi_init (NMDeviceWifi *self)
+ 	c_list_init (&priv->aps_lst_head);
+ 
+ 	priv->mode = NM_802_11_MODE_INFRA;
++	priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
+ }
+ 
+ static void
+diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
+index 9bd662a..33a05ab 100644
+--- a/src/platform/nm-linux-platform.c
++++ b/src/platform/nm-linux-platform.c
+@@ -6092,6 +6092,13 @@ wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean ru
+ 	wifi_utils_indicate_addressing_running (wifi_data, running);
+ }
+ 
++static NMSettingWirelessWakeOnWLan
++wifi_get_wake_on_wlan (NMPlatform *platform, int ifindex)
++{
++	WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE);
++	return wifi_utils_get_wake_on_wlan (wifi_data);
++}
++
+ static gboolean
+ wifi_set_wake_on_wlan (NMPlatform *platform, int ifindex,
+                        NMSettingWirelessWakeOnWLan wowl)
+@@ -7238,6 +7245,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
+ 	platform_class->wifi_set_powersave = wifi_set_powersave;
+ 	platform_class->wifi_find_frequency = wifi_find_frequency;
+ 	platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running;
++	platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan;
+ 	platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan;
+ 
+ 	platform_class->mesh_get_channel = mesh_get_channel;
+diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
+index f75019e..96bb292 100644
+--- a/src/platform/nm-platform.c
++++ b/src/platform/nm-platform.c
+@@ -2888,6 +2888,16 @@ nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gbo
+ 	klass->wifi_indicate_addressing_running (self, ifindex, running);
+ }
+ 
++NMSettingWirelessWakeOnWLan
++nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex)
++{
++	_CHECK_SELF (self, klass, FALSE);
++
++	g_return_val_if_fail (ifindex > 0, FALSE);
++
++	return klass->wifi_get_wake_on_wlan (self, ifindex);
++}
++
+ gboolean
+ nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl)
+ {
+diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
+index 866df73..84d10d2 100644
+--- a/src/platform/nm-platform.h
++++ b/src/platform/nm-platform.h
+@@ -868,6 +868,7 @@ typedef struct {
+ 	void        (*wifi_set_powersave)    (NMPlatform *, int ifindex, guint32 powersave);
+ 	guint32     (*wifi_find_frequency)   (NMPlatform *, int ifindex, const guint32 *freqs);
+ 	void        (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running);
++	NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex);
+ 	gboolean    (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl);
+ 
+ 	guint32     (*mesh_get_channel)      (NMPlatform *, int ifindex);
+@@ -1247,6 +1248,7 @@ void        nm_platform_wifi_set_mode         (NMPlatform *self, int ifindex, NM
+ void        nm_platform_wifi_set_powersave    (NMPlatform *self, int ifindex, guint32 powersave);
+ guint32     nm_platform_wifi_find_frequency   (NMPlatform *self, int ifindex, const guint32 *freqs);
+ void        nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running);
++NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex);
+ gboolean    nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl);
+ 
+ guint32     nm_platform_mesh_get_channel      (NMPlatform *self, int ifindex);
+diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c
+index 6c2ff3f..518e39c 100644
+--- a/src/platform/wifi/wifi-utils-nl80211.c
++++ b/src/platform/wifi/wifi-utils-nl80211.c
+@@ -271,6 +271,60 @@ nla_put_failure:
+ 	return FALSE;
+ }
+ 
++static int
++nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg)
++{
++	NMSettingWirelessWakeOnWLan *wowl = arg;
++	struct nlattr *attrs[NL80211_ATTR_MAX + 1];
++	struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG];
++	struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg));
++
++	nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
++	           genlmsg_attrlen(gnlh, 0), NULL);
++
++	if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
++		return NL_SKIP;
++
++	nla_parse (trig, MAX_NL80211_WOWLAN_TRIG,
++	           nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
++	           nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
++	           NULL);
++
++	*wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE;
++	if (trig[NL80211_WOWLAN_TRIG_ANY])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY;
++	if (trig[NL80211_WOWLAN_TRIG_DISCONNECT])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT;
++	if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC;
++	if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE;
++	if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST;
++	if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE;
++	if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE;
++	if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION])
++		*wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP;
++
++	return NL_SKIP;
++}
++
++static NMSettingWirelessWakeOnWLan
++wifi_nl80211_get_wake_on_wlan (WifiData *data)
++{
++	WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
++	NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
++	nm_auto_nlmsg struct nl_msg *msg = NULL;
++
++	msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0);
++
++	nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl);
++
++	return wowl;
++}
++
+ static gboolean
+ wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
+ {
+@@ -282,11 +336,11 @@ wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
+ 	if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE)
+ 		return TRUE;
+ 
+-	msg = nl80211_alloc_msg(nl80211, NL80211_CMD_SET_WOWLAN, 0);
++	msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0);
+ 	if (!msg)
+ 		return FALSE;
+ 
+-	triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
++	triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS);
+ 
+ 	if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY))
+ 		NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY);
+@@ -306,7 +360,8 @@ wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
+ 	nla_nest_end(msg, triggers);
+ 
+ 	err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
+-	return err ? FALSE : TRUE;
++
++	return err >= 0;
+ 
+ nla_put_failure:
+ 	return FALSE;
+@@ -887,6 +942,7 @@ wifi_nl80211_init (int ifindex)
+ 		.get_mode = wifi_nl80211_get_mode,
+ 		.set_mode = wifi_nl80211_set_mode,
+ 		.set_powersave = wifi_nl80211_set_powersave,
++		.get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan,
+ 		.set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan,
+ 		.get_freq = wifi_nl80211_get_freq,
+ 		.find_freq = wifi_nl80211_find_freq,
+diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h
+index 627108c..dc5dec0 100644
+--- a/src/platform/wifi/wifi-utils-private.h
++++ b/src/platform/wifi/wifi-utils-private.h
+@@ -34,6 +34,9 @@ typedef struct {
+ 	/* Set power saving mode on an interface */
+ 	gboolean (*set_powersave) (WifiData *data, guint32 powersave);
+ 
++	/* Get WakeOnWLAN configuration on an interface */
++	NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (WifiData *data);
++
+ 	/* Set WakeOnWLAN mode on an interface */
+ 	gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl);
+ 
+diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c
+index b3dd92b..b704be1 100644
+--- a/src/platform/wifi/wifi-utils.c
++++ b/src/platform/wifi/wifi-utils.c
+@@ -112,6 +112,16 @@ wifi_utils_set_powersave (WifiData *data, guint32 powersave)
+ 	return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE;
+ }
+ 
++NMSettingWirelessWakeOnWLan
++wifi_utils_get_wake_on_wlan (WifiData *data)
++{
++	g_return_val_if_fail (data != NULL, FALSE);
++
++	return   data->klass->get_wake_on_wlan
++	       ? data->klass->get_wake_on_wlan (data)
++	       : NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
++}
++
+ gboolean
+ wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
+ {
+diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h
+index c69561d..e454b71 100644
+--- a/src/platform/wifi/wifi-utils.h
++++ b/src/platform/wifi/wifi-utils.h
+@@ -67,6 +67,8 @@ gboolean wifi_utils_get_wowlan (WifiData *data);
+ 
+ gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave);
+ 
++NMSettingWirelessWakeOnWLan wifi_utils_get_wake_on_wlan (WifiData *data);
++
+ gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl);
+ 
+ /* OLPC Mesh-only functions */
diff -pruN 1.26.2-1/debian/patches/Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch 1.26.2-1ubuntu1/debian/patches/Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
--- 1.26.2-1/debian/patches/Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,35 @@
+From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
+Date: Thu, 12 May 2016 22:25:32 +0800
+Subject: Provide access to some of NM's interfaces to whoopsie.
+
+Whoopsie is the crash database reporting daemon. It needs access to some of
+the information NM keeps about devices to avoid sending data over the network
+when connected to 3G or other systems that are potentially billable.
+---
+ src/org.freedesktop.NetworkManager.conf | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/src/org.freedesktop.NetworkManager.conf b/src/org.freedesktop.NetworkManager.conf
+index 6be1feb..3dd2350 100644
+--- a/src/org.freedesktop.NetworkManager.conf
++++ b/src/org.freedesktop.NetworkManager.conf
+@@ -37,6 +37,19 @@
+         <allow own="org.freedesktop.NetworkManager.dnsmasq"/>
+         <allow send_destination="org.freedesktop.NetworkManager.dnsmasq"/>
+     </policy>
++    <policy user="whoopsie">
++            <allow send_destination="org.freedesktop.NetworkManager"/>
++            <allow send_destination="org.freedesktop.NetworkManager"
++                   send_interface="org.freedesktop.DBus.Introspectable"/>
++            <allow send_destination="org.freedesktop.NetworkManager"
++                   send_interface="org.freedesktop.DBus.Properties"/>
++            <allow send_destination="org.freedesktop.NetworkManager"
++                   send_interface="org.freedesktop.NetworkManager"/>
++            <allow send_destination="org.freedesktop.NetworkManager"
++                   send_interface="org.freedesktop.NetworkManager.Connection.Active"/>
++            <allow send_destination="org.freedesktop.NetworkManager"
++                   send_interface="org.freedesktop.NetworkManager.Device"/>
++    </policy>
+     <policy context="default">
+         <deny own="org.freedesktop.NetworkManager"/>
+ 
diff -pruN 1.26.2-1/debian/patches/series 1.26.2-1ubuntu1/debian/patches/series
--- 1.26.2-1/debian/patches/series	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/series	2020-08-31 09:09:40.000000000 +0000
@@ -1 +1,6 @@
 Force-online-state-with-unmanaged-devices.patch
+
+# Ubuntu patches
+Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+Update-dnsmasq-parameters.patch
+
diff -pruN 1.26.2-1/debian/patches/Update-dnsmasq-parameters.patch 1.26.2-1ubuntu1/debian/patches/Update-dnsmasq-parameters.patch
--- 1.26.2-1/debian/patches/Update-dnsmasq-parameters.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/patches/Update-dnsmasq-parameters.patch	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,55 @@
+From: =?utf-8?q?St=C3=A9phane_Graber?= <stephane.graber@canonical.com>
+Date: Thu, 12 May 2016 22:44:06 +0800
+Subject: Update dnsmasq parameters
+
+Disable caching since it's a potential security issue (local dns cache poisoning).
+
+See also: https://blueprints.launchpad.net/ubuntu/+spec/foundations-p-dns-resolving
+---
+ src/dns/nm-dns-dnsmasq.c | 4 ++--
+ src/dns/nm-dns-manager.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+Index: network-manager-1.24.0/src/dns/nm-dns-dnsmasq.c
+===================================================================
+--- network-manager-1.24.0.orig/src/dns/nm-dns-dnsmasq.c
++++ network-manager-1.24.0/src/dns/nm-dns-dnsmasq.c
+@@ -494,8 +494,8 @@ _gl_pid_spawn_next_step (void)
+ 	argv[argv_idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
+ 	argv[argv_idx++] = "--bind-interfaces";
+ 	argv[argv_idx++] = "--pid-file=" PIDFILE;
+-	argv[argv_idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
+-	argv[argv_idx++] = "--cache-size=400";
++	argv[argv_idx++] = "--listen-address=127.0.1.1"; /* Should work for both 4 and 6 */
++	argv[argv_idx++] = "--cache-size=0";
+ 	argv[argv_idx++] = "--clear-on-reload"; /* clear cache when dns server changes */
+ 	argv[argv_idx++] = "--conf-file=/dev/null"; /* avoid loading /etc/dnsmasq.conf */
+ 	argv[argv_idx++] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */
+Index: network-manager-1.24.0/src/dns/nm-dns-manager.c
+===================================================================
+--- network-manager-1.24.0.orig/src/dns/nm-dns-manager.c
++++ network-manager-1.24.0/src/dns/nm-dns-manager.c
+@@ -1526,12 +1526,12 @@ plugin_skip:
+ 	                            NM_CAST_STRV_CC (nameservers),
+ 	                            NM_CAST_STRV_CC (options));
+ 
+-	/* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf
++	/* If caching was successful, we only send 127.0.1.1 to /etc/resolv.conf
+ 	 * to ensure that the glibc resolver doesn't try to round-robin nameservers,
+ 	 * but only uses the local caching nameserver.
+ 	 */
+ 	if (caching) {
+-		const char *lladdr = "127.0.0.1";
++		const char *lladdr = "127.0.1.1";
+ 
+ 		if (NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)) {
+ 			/* systemd-resolved uses a different link-local address */
+@@ -1825,7 +1825,7 @@ nm_dns_manager_stop (NMDnsManager *self)
+ 	_LOGT ("stopping...");
+ 
+ 	/* If we're quitting, leave a valid resolv.conf in place, not one
+-	 * pointing to 127.0.0.1 if dnsmasq was active.  But if we haven't
++	 * pointing to 127.0.1.1 if dnsmasq was active.  But if we haven't
+ 	 * done any DNS updates yet, there's no reason to touch resolv.conf
+ 	 * on shutdown.
+ 	 */
diff -pruN 1.26.2-1/debian/rules 1.26.2-1ubuntu1/debian/rules
--- 1.26.2-1/debian/rules	2020-08-19 08:30:53.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/rules	2020-08-31 09:09:40.000000000 +0000
@@ -2,12 +2,20 @@
 
 include /usr/share/dpkg/architecture.mk
 
+# Without that the tests fail, cannot register existing type 'NMAgentManagerError'
+LDFLAGS=$(shell echo $$LDFLAGS | sed -e 's/-Wl,-Bsymbolic-functions//')
+export LDFLAGS
+
+ifeq ($(shell dpkg-vendor --is Ubuntu && echo yes) $(DEB_HOST_ARCH), yes i386)
+   BUILD_PACKAGES += -Nnetwork-manager
+endif
+
 export PYTHON=/usr/bin/python3
 
 PPPD_PLUGIN_DIR := $(shell dh_ppp --plugin-dir)
 
 %:
-	dh $@ --with gir,ppp
+	dh $@ --with gir,ppp $(BUILD_PACKAGES)
 
 autoreconf:
 	gtkdocize --copy
@@ -23,7 +31,7 @@ override_dh_auto_configure:
 		--runstatedir=/run \
 		--with-pppd-plugin-dir=$(PPPD_PLUGIN_DIR) \
 		--with-pppd=/usr/sbin/pppd \
-		--with-resolvconf=/sbin/resolvconf \
+		--with-resolvconf=no \
 		--with-dhclient=/sbin/dhclient \
 		--with-iptables=/usr/sbin/iptables \
 		--with-dnsmasq=/usr/sbin/dnsmasq \
@@ -38,6 +46,7 @@ override_dh_auto_configure:
 		--with-nmtui \
 		--with-nmcli \
 		--with-selinux \
+		--with-tests \
 		--with-libaudit \
 		--with-iwd \
 		--without-dhcpcanon \
@@ -59,11 +68,19 @@ override_dh_auto_configure:
 
 override_dh_install:
 	find debian/tmp -name '*.la' -print -delete
+	rm -vf $(CURDIR)/debian/tmp/etc/init.d/NetworkManager
 	dh_install
 
 override_dh_missing:
 	dh_missing --fail-missing
 
+	# copy powersave configuration
+	mkdir -p debian/network-manager/etc/NetworkManager/conf.d
+	cp debian/default-wifi-powersave-on.conf debian/network-manager/etc/NetworkManager/conf.d/
+
+override_dh_installinit:
+	dh_installinit --noscripts
+
 override_dh_makeshlibs:
 	dh_makeshlibs -X/usr/lib/$(DEB_HOST_MULTIARCH)/NetworkManager/ -X/usr/lib/pppd/
 
@@ -73,3 +90,8 @@ override_dh_installsystemd:
 
 override_dh_ppp:
 	dh_ppp --breaks
+
+override_dh_auto_test:
+ifeq (, $(filter nocheck, $(DEB_BUILD_OPTIONS)))
+	make check || ( find . -name test-suite.log -exec cat {} \;; exit 1; )
+endif
diff -pruN 1.26.2-1/debian/source_network-manager.py 1.26.2-1ubuntu1/debian/source_network-manager.py
--- 1.26.2-1/debian/source_network-manager.py	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/source_network-manager.py	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,82 @@
+'''Apport package hook for Network Manager
+
+(c) 2008 Canonical Ltd.
+Contributors:
+Matt Zimmerman <mdz@canonical.com>
+Martin Pitt <martin.pitt@canonical.com>
+Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
+Thomas Bechtold <thomasbechtold@jpberlin.de>
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
+the full text of the license.
+'''
+
+import os
+import subprocess
+from apport.hookutils import *
+
+def _network_interfaces():
+    interfaces = []
+    output = command_output(['ls', '-1', '/sys/class/net'])
+    for device in output.split('\n'):
+       interfaces.append(device)
+
+    return interfaces
+
+def _device_details(device):
+    details = command_output(['udevadm', 'info', '--query=all', '--path', '/sys/class/net/%s' % device])
+
+    # add the only extra thing of use from hal we don't get from udev.
+    details = details + "\nX: INTERFACE_MAC="
+    details = details + command_output(['cat', '/sys/class/net/%s/address' % device])
+    return details
+
+def add_info(report, ui=None):
+    attach_network(report)
+    attach_wifi(report)
+
+    #this is the old config file (still read by NM if available)
+    attach_file_if_exists(report, '/etc/NetworkManager/nm-system-settings.conf', 'nm-system-settings.conf')
+
+    #the new default config file
+    attach_file_if_exists(report, '/etc/NetworkManager/NetworkManager.conf', 'NetworkManager.conf')
+
+    # attach NetworkManager.state: it gives us good hints in rfkill-related bugs.
+    attach_file_if_exists(report, '/var/lib/NetworkManager/NetworkManager.state', 'NetworkManager.state')
+
+    for interface in _network_interfaces():
+        key = 'NetDevice.%s' % interface
+        report[key] = _device_details(interface)
+
+    interesting_modules = { 'ndiswrapper' : 'driver-ndiswrapper',
+                            'ath_hal' : 'driver-madwifi',
+                            'b44' : 'driver-b44' }
+    interesting_modules_loaded = []
+    tags = []
+    for line in open('/proc/modules'):
+        module = line.split()[0]
+        if module in interesting_modules:
+            tags.append(interesting_modules[module])
+            interesting_modules_loaded.append(module)
+
+    if interesting_modules_loaded:
+        report['InterestingModules'] = ' '.join(interesting_modules_loaded)
+        report.setdefault('Tags', '')
+        report['Tags'] += ' ' + ' '.join(tags)
+
+    #add output of nmcli
+    report['nmcli-nm'] = command_output(['nmcli', '-f', 'all', 'gen'])
+    report['nmcli-dev'] = command_output(['nmcli', '-f', 'all', 'dev'])
+    report['nmcli-con'] = command_output(['nmcli', '-f', 'all', 'con'])
+
+
+## Only for debugging ##
+if __name__ == '__main__':
+    report = {}
+    report['CrashDB'] = 'ubuntu'
+    add_info(report, None)
+    for key in report:
+        print('%s: %s' % (key, report[key]))
diff -pruN 1.26.2-1/debian/tests/control 1.26.2-1ubuntu1/debian/tests/control
--- 1.26.2-1/debian/tests/control	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/control	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,15 @@
+Tests: wpa-dhclient
+Depends: python3, hostapd, dnsmasq-base, wpasupplicant, isc-dhcp-client, iw
+Restrictions: needs-root allow-stderr isolation-machine skippable
+
+Tests: nm.py
+Depends: python3, dnsmasq-base, isc-dhcp-client, gir1.2-nm-1.0, network-manager, hostapd, iw, python3-dbusmock, python3-netaddr
+Restrictions: needs-root isolation-machine skippable
+
+Tests: killswitches-no-urfkill
+Depends: network-manager, build-essential, linux-headers-generic [!i386], rfkill
+Restrictions: needs-root allow-stderr isolation-machine skippable
+
+Tests: urfkill-integration
+Depends: network-manager, build-essential, linux-headers-generic [!i386], rfkill, urfkill
+Restrictions: needs-root allow-stderr isolation-machine skippable
diff -pruN 1.26.2-1/debian/tests/fake-rfkill.c 1.26.2-1ubuntu1/debian/tests/fake-rfkill.c
--- 1.26.2-1/debian/tests/fake-rfkill.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/fake-rfkill.c	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,51 @@
+#include <linux/rfkill.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+
+static struct rfkill *rfk;
+
+static void test_poll(struct rfkill *rfkill, void *data)
+{
+	printk(KERN_DEBUG "poll test rfkill\n");
+}
+
+static void test_query(struct rfkill *rfkill, void *data)
+{
+	printk(KERN_DEBUG "query test rfkill\n");
+}
+
+static int test_set_block(void *data, bool blocked)
+{
+	printk(KERN_DEBUG "set test rfkill (%s)\n",
+		blocked ? "blocked" : "active");
+	return 0;
+}
+
+static struct rfkill_ops ops = {
+	.poll = test_poll,
+	.query = test_query,
+	.set_block = test_set_block,
+};
+
+int mod_init(void)
+{
+	int err;
+
+	rfk = rfkill_alloc("fake", NULL, RFKILL_TYPE_WLAN, &ops, NULL);
+	if (!rfk)
+		return -ENOMEM;
+	err = rfkill_register(rfk);
+	if (err)
+		rfkill_destroy(rfk);
+	return err;
+}
+module_init(mod_init);
+
+void mod_exit(void)
+{
+	rfkill_unregister(rfk);
+	rfkill_destroy(rfk);
+}
+module_exit(mod_exit);
diff -pruN 1.26.2-1/debian/tests/killswitches-no-urfkill 1.26.2-1ubuntu1/debian/tests/killswitches-no-urfkill
--- 1.26.2-1/debian/tests/killswitches-no-urfkill	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/killswitches-no-urfkill	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+if dpkg --print-architecture | grep s390; then
+    echo "Skipping rfkill tests on s390 (LP: #1855009)"
+    exit 77
+fi
+
+if dpkg --print-architecture | grep i386; then
+    echo "Skipping rfkill tests on i386 (LP: #1855183)"
+    exit 77
+fi
+
+set -e
+
+make -f debian/tests/Makefile fake-rfkill
+# poor man's dependency resolver
+DEPS=$(modinfo debian/tests/fake-rfkill.ko | sed -n '/depends:/ {s/^.*://; s/[[:space:]]*$//; p}')
+[ -z "$DEPS" ] || modprobe "$DEPS"
+insmod debian/tests/fake-rfkill.ko
+
+fake_id=$(rfkill list | grep fake | awk -F: '{ print $1; }')
+
+service NetworkManager start
+sleep 30
+
+# test blocking the device
+rfkill block $fake_id
+if ! rfkill list $fake_id | grep 'Soft' | awk '{ print $3; }' | grep -qc yes; then
+	echo "ERROR: could not block fake device"
+	rmmod fake-rfkill || true
+	exit 1
+fi
+
+# The systemd-rfkill service starts up whenever rfkill changes state, so on a
+# 1-cpu system that might delay the event change from reaching nm before the
+# check below, causing this test to fail.  The settle added here delays the
+# nmcli check until after the rfkill uevent has definitely been processed.
+udevadm settle
+
+if ! LC_MESSAGES=C nmcli radio wifi | grep -qc disabled; then
+	echo "ERROR: NM could not track device state."
+	rmmod fake-rfkill || true
+	exit 1
+fi
+
+# test unblocking the device
+rfkill unblock $fake_id
+if ! rfkill list $fake_id | grep 'Soft' | awk '{ print $3; }' | grep -qc no; then
+	echo "ERROR: could not unblock fake device"
+	rmmod fake-rfkill || true
+	exit 1
+fi
+
+# same reason as above, however since systemd-rfkill stays running for 30 secs or so
+# it's unlikely that it would start up again here, but it's still safer to call settle
+udevadm settle
+
+if ! LC_MESSAGES=C nmcli radio wifi | grep -qc enabled; then
+	echo "ERROR: NM could not track device state to enabled."
+	rmmod fake-rfkill || true
+	exit 1
+fi
+
+rmmod fake-rfkill
+make -f debian/tests/Makefile clean-rfkill
+
+echo OK
diff -pruN 1.26.2-1/debian/tests/Makefile 1.26.2-1ubuntu1/debian/tests/Makefile
--- 1.26.2-1/debian/tests/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/Makefile	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,8 @@
+
+obj-m += fake-rfkill.o
+
+fake-rfkill:
+	make -C /lib/modules/$(shell uname -r)/build KBUILD_SRC=/lib/modules/$(shell uname -r)/build M=$(shell pwd)/debian/tests
+
+clean-rfkill:
+	make -C /lib/modules/$(shell uname -r)/build KBUILD_SRC=/lib/modules/$(shell uname -r)/build M=$(shell pwd)/debian/tests clean
diff -pruN 1.26.2-1/debian/tests/network_test_base.py 1.26.2-1ubuntu1/debian/tests/network_test_base.py
--- 1.26.2-1/debian/tests/network_test_base.py	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/network_test_base.py	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,360 @@
+'''
+Base class for network related tests.
+
+This provides fake wifi devices with mac80211_hwsim and hostapd, test ethernet
+devices with veth, utility functions to start wpasupplicant, dnsmasq, get/set
+rfkill status, and some utility functions.
+'''
+
+__author__ = 'Martin Pitt <martin.pitt@ubuntu.com>'
+__copyright__ = '(C) 2013 Canonical Ltd.'
+__license__ = 'GPL v2 or later'
+
+import sys
+import os
+import os.path
+import time
+import tempfile
+import subprocess
+import re
+import unittest
+import traceback
+import functools
+from glob import glob
+
+# check availability of programs, and cleanly skip test if they are not
+# available
+for program in ['wpa_supplicant', 'hostapd', 'dnsmasq', 'dhclient']:
+    if subprocess.call(['which', program], stdout=subprocess.PIPE) != 0:
+        sys.stderr.write('%s is required for this test suite, but not available. Skipping\n' % program)
+        sys.exit(0)
+
+
+class NetworkTestBase(unittest.TestCase):
+    '''Common functionality for network test cases
+
+    setUp() creates two test wlan devices, one for a simulated access point
+    (self.dev_w_ap), the other for a simulated client device
+    (self.dev_w_client), and two test ethernet devices (self.dev_e_ap and
+    self.dev_e_client).
+
+    Each test should call self.setup_ap() or self.setup_eth() with the desired
+    configuration.
+    '''
+    @classmethod
+    def setUpClass(klass):
+        # ensure we have this so that iw works
+        subprocess.check_call(['modprobe', 'cfg80211'])
+
+        # set regulatory domain "EU", so that we can use 80211.a 5 GHz channels
+        out = subprocess.check_output(['iw', 'reg', 'get'], universal_newlines=True)
+        m = re.match('^(?:global\n)?country (\S+):', out)
+        assert m
+        klass.orig_country = m.group(1)
+        subprocess.check_call(['iw', 'reg', 'set', 'EU'])
+
+    @classmethod
+    def tearDownClass(klass):
+        subprocess.check_call(['iw', 'reg', 'set', klass.orig_country])
+        os.remove('/run/udev/rules.d/99-nm-veth-test.rules')
+
+    @classmethod
+    def create_devices(klass):
+        '''Create Access Point and Client devices with mac80211_hwsim and veth'''
+
+        klass.dev_e_ap = 'veth42'
+        klass.dev_e_client = 'eth42'
+
+        if os.path.exists('/sys/module/mac80211_hwsim'):
+            raise SystemError('mac80211_hwsim module already loaded')
+        if os.path.exists('/sys/class/net/' + klass.dev_e_client):
+            raise SystemError('%s interface already exists' % klass.dev_e_client)
+
+        # ensure NM can manage our fake eths
+        os.makedirs('/run/udev/rules.d', exist_ok=True)
+        with open('/run/udev/rules.d/99-nm-veth-test.rules', 'w') as f:
+            f.write('ENV{ID_NET_DRIVER}=="veth", ENV{INTERFACE}=="%s", ENV{NM_UNMANAGED}="0"\n' % klass.dev_e_client)
+        subprocess.check_call(['udevadm', 'control', '--reload'])
+
+        # create virtual ethernet devs
+        subprocess.check_call(['ip', 'link', 'add', 'name', klass.dev_e_client, 'type',
+                               'veth', 'peer', 'name', klass.dev_e_ap])
+
+        # create virtual wlan devs
+        before_wlan = set([c for c in os.listdir('/sys/class/net') if c.startswith('wlan')])
+        subprocess.check_call(['modprobe', 'mac80211_hwsim'])
+        # wait 5 seconds for fake devices to appear
+        timeout = 50
+        while timeout > 0:
+            after_wlan = set([c for c in os.listdir('/sys/class/net') if c.startswith('wlan')])
+            if len(after_wlan) - len(before_wlan) >= 2:
+                break
+            timeout -= 1
+            time.sleep(0.1)
+        else:
+            raise SystemError('timed out waiting for fake devices to appear')
+
+        devs = list(after_wlan - before_wlan)
+        klass.dev_w_ap = devs[0]
+        klass.dev_w_client = devs[1]
+
+        # determine and store MAC addresses
+        with open('/sys/class/net/%s/address' % klass.dev_w_ap) as f:
+            klass.mac_w_ap = f.read().strip().upper()
+        with open('/sys/class/net/%s/address' % klass.dev_w_client) as f:
+            klass.mac_w_client = f.read().strip().upper()
+        with open('/sys/class/net/%s/address' % klass.dev_e_ap) as f:
+            klass.mac_e_ap = f.read().strip().upper()
+        with open('/sys/class/net/%s/address' % klass.dev_e_client) as f:
+            klass.mac_e_client = f.read().strip().upper()
+        #print('Created fake devices: AP: %s, client: %s' % (klass.dev_w_ap, klass.dev_w_client))
+
+    @classmethod
+    def shutdown_devices(klass):
+        '''Remove test wlan devices'''
+
+        subprocess.check_call(['rmmod', 'mac80211_hwsim'])
+        subprocess.check_call(['ip', 'link', 'del', 'dev', klass.dev_e_ap])
+        klass.dev_w_ap = None
+        klass.dev_w_client = None
+        klass.dev_e_ap = None
+        klass.dev_e_client = None
+
+    @classmethod
+    def get_rfkill(klass, interface):
+        '''Get rfkill status of an interface.
+
+        Returns whether the interface is blocked, i. e. "True" for blocked,
+        "False" for enabled.
+        '''
+        with open(klass._rfkill_attribute(interface)) as f:
+            val = f.read()
+        return val == '1'
+
+    @classmethod
+    def set_rfkill(klass, interface, block):
+        '''Set rfkill status of an interface
+
+        Use block==True for disabling ("killswitching") an interface,
+        block==False to re-enable.
+        '''
+        with open(klass._rfkill_attribute(interface), 'w') as f:
+            f.write(block and '1' or '0')
+
+    def run(self, result=None):
+        '''Show log files on failed tests'''
+
+        if result:
+            orig_err_fail = len(result.errors) + len(result.failures)
+        super().run(result)
+        if hasattr(self, 'workdir'):
+            logs = glob(os.path.join(self.workdir, '*.log'))
+            if result and len(result.errors) + len(result.failures) > orig_err_fail:
+                for log_file in logs:
+                    with open(log_file) as f:
+                        print('\n----- %s -----\n%s\n------\n'
+                              % (os.path.basename(log_file), f.read()))
+
+            # clean up log files, so that we don't see ones from previous tests
+            for log_file in logs:
+                os.unlink(log_file)
+
+    def setUp(self):
+        '''Create test devices and workdir'''
+
+        self.create_devices()
+        self.addCleanup(self.shutdown_devices)
+        self.workdir_obj = tempfile.TemporaryDirectory()
+        self.workdir = self.workdir_obj.name
+
+        # create static entropy file to avoid draining/blocking on /dev/random
+        self.entropy_file = os.path.join(self.workdir, 'entropy')
+        with open(self.entropy_file, 'wb') as f:
+            f.write(b'012345678901234567890')
+
+    def setup_ap(self, hostapd_conf, ipv6_mode):
+        '''Set up simulated access point
+
+        On self.dev_w_ap, run hostapd with given configuration. Setup dnsmasq
+        according to ipv6_mode, see start_dnsmasq().
+
+        This is torn down automatically at the end of the test.
+        '''
+        # give our AP an IP
+        subprocess.check_call(['ip', 'a', 'flush', 'dev', self.dev_w_ap])
+        if ipv6_mode is not None:
+            subprocess.check_call(['ip', 'a', 'add', '2600::1/64', 'dev', self.dev_w_ap])
+        else:
+            subprocess.check_call(['ip', 'a', 'add', '192.168.5.1/24', 'dev', self.dev_w_ap])
+
+        self.start_hostapd(hostapd_conf)
+        self.start_dnsmasq(ipv6_mode, self.dev_w_ap)
+
+    def setup_eth(self, ipv6_mode, start_dnsmasq=True):
+        '''Set up simulated ethernet router
+
+        On self.dev_e_ap, run dnsmasq according to ipv6_mode, see
+        start_dnsmasq().
+
+        This is torn down automatically at the end of the test.
+        '''
+        # give our router an IP
+        subprocess.check_call(['ip', 'a', 'flush', 'dev', self.dev_e_ap])
+        if ipv6_mode is not None:
+            subprocess.check_call(['ip', 'a', 'add', '2600::1/64', 'dev', self.dev_e_ap])
+        else:
+            subprocess.check_call(['ip', 'a', 'add', '192.168.5.1/24', 'dev', self.dev_e_ap])
+        subprocess.check_call(['ip', 'link', 'set', self.dev_e_ap, 'up'])
+        # we don't really want to up the client iface already, but veth doesn't
+        # work otherwise (no link detected)
+        subprocess.check_call(['ip', 'link', 'set', self.dev_e_client, 'up'])
+
+        if start_dnsmasq:
+            self.start_dnsmasq(ipv6_mode, self.dev_e_ap)
+
+    def start_wpasupp(self, conf):
+        '''Start wpa_supplicant on client interface'''
+
+        w_conf = os.path.join(self.workdir, 'wpasupplicant.conf')
+        with open(w_conf, 'w') as f:
+            f.write('ctrl_interface=%s\nnetwork={\n%s\n}\n' % (self.workdir, conf))
+        log = os.path.join(self.workdir, 'wpasupp.log')
+        p = subprocess.Popen(['wpa_supplicant', '-Dwext', '-i', self.dev_w_client,
+                              '-e', self.entropy_file, '-c', w_conf, '-f', log],
+                             stderr=subprocess.PIPE)
+        self.addCleanup(p.wait)
+        self.addCleanup(p.terminate)
+        # TODO: why does this sometimes take so long?
+        self.poll_text(log, 'CTRL-EVENT-CONNECTED', timeout=200)
+
+    def wrap_process(self, fn, *args, **kwargs):
+        '''Run a test method in a separate process.
+
+        Run test method fn(*args, **kwargs) in a child process. If that raises
+        any exception, it gets propagated to the main process and
+        wrap_process() fails with that exception.
+        '''
+        # exception from subprocess is propagated through this file
+        exc_path = os.path.join(self.workdir, 'exc')
+        try:
+            os.unlink(exc_path)
+        except OSError:
+            pass
+
+        pid = os.fork()
+
+        # run the actual test in the child
+        if pid == 0:
+            # short-circuit tearDownClass(), as this will be done by the parent
+            # process
+            self.addCleanup(os._exit, 0)
+            try:
+                fn(*args, **kwargs)
+            except:
+                with open(exc_path, 'w') as f:
+                    f.write(traceback.format_exc())
+                raise
+        else:
+            # get success/failure state from child
+            os.waitpid(pid, 0)
+            # propagate exception
+            if os.path.exists(exc_path):
+                with open(exc_path) as f:
+                    self.fail(f.read())
+
+    #
+    # Internal implementation details
+    #
+
+    @classmethod
+    def poll_text(klass, logpath, string, timeout=50):
+        '''Poll log file for a given string with a timeout.
+
+        Timeout is given in deciseconds.
+        '''
+        log = ''
+        while timeout > 0:
+            if os.path.exists(logpath):
+                break
+            timeout -= 1
+            time.sleep(0.1)
+        assert timeout > 0, 'Timed out waiting for file %s to appear' % logpath
+
+        with open(logpath) as f:
+            while timeout > 0:
+                line = f.readline()
+                if line:
+                    log += line
+                    if string in line:
+                        break
+                    continue
+                timeout -= 1
+                time.sleep(0.1)
+
+        assert timeout > 0, 'Timed out waiting for "%s":\n------------\n%s\n-------\n' % (string, log)
+
+    def start_hostapd(self, conf):
+        hostapd_conf = os.path.join(self.workdir, 'hostapd.conf')
+        with open(hostapd_conf, 'w') as f:
+            f.write('interface=%s\ndriver=nl80211\n' % self.dev_w_ap)
+            f.write(conf)
+
+        log = os.path.join(self.workdir, 'hostapd.log')
+        p = subprocess.Popen(['hostapd', '-e', self.entropy_file, '-f', log, hostapd_conf],
+                             stdout=subprocess.PIPE)
+        self.addCleanup(p.wait)
+        self.addCleanup(p.terminate)
+        self.poll_text(log, '' + self.dev_w_ap + ': AP-ENABLED')
+
+    def start_dnsmasq(self, ipv6_mode, iface):
+        '''Start dnsmasq.
+
+        If ipv6_mode is None, IPv4 is set up with DHCP. If it is not None, it
+        must be a valid dnsmasq mode, i. e. a combination of "ra-only",
+        "slaac", "ra-stateless", and "ra-names". See dnsmasq(8).
+        '''
+        if ipv6_mode is None:
+            dhcp_range = '192.168.5.10,192.168.5.200'
+        else:
+            dhcp_range = '2600::10,2600::20'
+            if ipv6_mode:
+                dhcp_range += ',' + ipv6_mode
+
+        self.dnsmasq_log = os.path.join(self.workdir, 'dnsmasq.log')
+        lease_file = os.path.join(self.workdir, 'dnsmasq.leases')
+
+        p = subprocess.Popen(['dnsmasq', '--keep-in-foreground', '--log-queries',
+                              '--log-facility=' + self.dnsmasq_log,
+                              '--conf-file=/dev/null',
+                              '--dhcp-leasefile=' + lease_file,
+                              '--bind-interfaces',
+                              '--interface=' + iface,
+                              '--except-interface=lo',
+                              '--enable-ra',
+                              '--dhcp-range=' + dhcp_range])
+        self.addCleanup(p.wait)
+        self.addCleanup(p.terminate)
+
+        if ipv6_mode is not None:
+            self.poll_text(self.dnsmasq_log, 'IPv6 router advertisement enabled')
+        else:
+            self.poll_text(self.dnsmasq_log, 'DHCP, IP range')
+
+    @classmethod
+    def _rfkill_attribute(klass, interface):
+        '''Return the path to interface's rfkill soft toggle in sysfs.'''
+
+        g = glob('/sys/class/net/%s/phy80211/rfkill*/soft' % interface)
+        assert len(g) == 1, 'Did not find exactly one "soft" rfkill attribute for %s: %s' % (
+            interface, str(g))
+        return g[0]
+
+
+def run_in_subprocess(fn):
+    '''Decorator for running fn in a child process'''
+
+    @functools.wraps(fn)
+    def wrapped(*args, **kwargs):
+        # args[0] is self
+        args[0].wrap_process(fn, *args, **kwargs)
+    return wrapped
diff -pruN 1.26.2-1/debian/tests/nm.py 1.26.2-1ubuntu1/debian/tests/nm.py
--- 1.26.2-1/debian/tests/nm.py	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/nm.py	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,881 @@
+#!/usr/bin/python3
+# Test NetworkManager on simulated network devices
+# For an interactive shell test, run "nm ColdplugWifi.shell", see below
+
+__author__ = 'Martin Pitt <martin.pitt@ubuntu.com>'
+__copyright__ = '(C) 2013 Canonical Ltd.'
+__license__ = 'GPL v2 or later'
+
+import sys
+import os
+import os.path
+import re
+import time
+import subprocess
+import socket
+import netaddr
+import unittest
+import ctypes
+
+try:
+    from dbusmock import DBusTestCase
+except ImportError:
+    DBusTestCase = object  # dummy so that the class declaration works
+
+import gi
+
+gi.require_version('NM', '1.0')
+from gi.repository import NM, GLib, Gio
+
+sys.path.append(os.path.dirname(__file__))
+import network_test_base
+
+SSID = 'fake net'
+
+# If True, NetworkManager logs directly to stdout, to watch logs in real time
+NM_LOG_STDOUT = os.getenv('NM_LOG_STDOUT', False)
+
+# avoid accidentally destroying any real config
+os.environ['GSETTINGS_BACKEND'] = 'memory'
+
+# we currently get a lot of WARNINGs/CRITICALs from GI (leaked objects from
+# previous test runs/main loops?) Redirect them to stdout, to avoid failing
+# autopkgtests
+os.dup2(sys.stdout.fileno(), sys.stderr.fileno())
+
+
+class NetworkManagerTest(network_test_base.NetworkTestBase):
+    '''Provide common functionality for NM tests'''
+
+    def start_nm(self, wait_iface=None, auto_connect=True):
+        '''Start NetworkManager and initialize client object
+
+        If wait_iface is given, wait until NM recognizes that interface.
+        Otherwise, just wait until NM has initialized (for coldplug mode).
+
+        If auto_connect is False, set the "no-auto-default=*" option to avoid
+        auto-connecting to wired devices.
+        '''
+        # mount tmpfses over system directories, to avoid destroying the
+        # production configuration, and isolating tests from each other
+        if not os.path.exists('/run/NetworkManager'):
+            os.mkdir('/run/NetworkManager')
+        for d in ['/etc/NetworkManager', '/var/lib/NetworkManager',
+                  '/run/NetworkManager']:
+            subprocess.check_call(['mount', '-n', '-t', 'tmpfs', 'none', d])
+            self.addCleanup(subprocess.call, ['umount', d])
+        os.mkdir('/etc/NetworkManager/system-connections')
+
+        # create local configuration; this allows us to have full control, and
+        # we also need to blacklist the AP device so that NM does not tear it
+        # down; we also blacklist any existing real interface to avoid
+        # interfering with it, and for getting predictable results
+        blacklist = ''
+        for iface in os.listdir('/sys/class/net'):
+            if iface == "bonding_masters":
+                continue
+            if iface != self.dev_w_client and iface != self.dev_e_client:
+                with open('/sys/class/net/%s/address' % iface) as f:
+                    if blacklist:
+                        blacklist += ';'
+                    blacklist += 'mac:%s' % f.read().strip()
+
+        conf = os.path.join(self.workdir, 'NetworkManager.conf')
+        extra_main = ''
+        if not auto_connect:
+            extra_main += 'no-auto-default=*\n'
+
+        with open(conf, 'w') as f:
+            f.write('[main]\nplugins=keyfile\n%s\n[keyfile]\nunmanaged-devices=%s\n' %
+                    (extra_main, blacklist))
+
+        if NM_LOG_STDOUT:
+            f_log = None
+        else:
+            log = os.path.join(self.workdir, 'NetworkManager.log')
+            f_log = os.open(log, os.O_CREAT | os.O_WRONLY | os.O_SYNC)
+
+        # build NM command line
+        argv = ['NetworkManager', '--log-level=debug', '--debug', '--config=' + conf]
+        # allow specifying extra arguments
+        argv += os.environ.get('NM_TEST_DAEMON_ARGS', '').strip().split()
+
+        p = subprocess.Popen(argv, stdout=f_log, stderr=subprocess.STDOUT)
+        # automatically terminate process at end of test case
+        self.addCleanup(p.wait)
+        self.addCleanup(p.terminate)
+        self.addCleanup(self.shutdown_connections)
+
+        if NM_LOG_STDOUT:
+            # let it initialize, then print a marker
+            time.sleep(1)
+            print('******* NM initialized *********\n\n')
+        else:
+            self.addCleanup(os.close, f_log)
+
+            # this should be fast, give it 2 s to initialize
+            if wait_iface:
+                self.poll_text(log, 'manager: (%s): new' % wait_iface, timeout=100)
+
+        self.nmclient = NM.Client.new()
+        self.assertTrue(self.nmclient.networking_get_enabled())
+
+        # FIXME: This certainly ought to be true, but isn't
+        #self.assertTrue(self.nmclient.get_manager_running())
+
+        # determine device objects
+        for d in self.nmclient.get_devices():
+            if d.props.interface == self.dev_w_ap:
+                self.assertEqual(d.get_device_type(), NM.DeviceType.WIFI)
+                self.assertEqual(d.get_driver(), 'mac80211_hwsim')
+                self.assertEqual(d.get_hw_address(), self.mac_w_ap)
+                self.nmdev_w_ap = d
+            elif d.props.interface == self.dev_w_client:
+                self.assertEqual(d.get_device_type(), NM.DeviceType.WIFI)
+                self.assertEqual(d.get_driver(), 'mac80211_hwsim')
+                # NM ≥ 1.4 randomizes MAC addresses by default, so we can't
+                # test for equality, just make sure it's not our AP
+                self.assertNotEqual(d.get_hw_address(), self.mac_w_ap)
+                self.nmdev_w = d
+            elif d.props.interface == self.dev_e_client:
+                self.assertEqual(d.get_device_type(), NM.DeviceType.VETH)
+                self.assertEqual(d.get_driver(), 'veth')
+                self.assertEqual(d.get_hw_address(), self.mac_e_client)
+                self.nmdev_e = d
+
+        self.assertTrue(hasattr(self, 'nmdev_w_ap'), 'Could not determine wifi AP NM device')
+        self.assertTrue(hasattr(self, 'nmdev_w'), 'Could not determine wifi client NM device')
+        self.assertTrue(hasattr(self, 'nmdev_e'), 'Could not determine eth client NM device')
+
+        self.process_glib_events()
+
+    def shutdown_connections(self):
+        '''Shut down all active NM connections.'''
+
+        if NM_LOG_STDOUT:
+            print('\n\n******* Shutting down NM connections *********')
+
+        # remove all created connections
+        for active_conn in self.nmclient.get_active_connections():
+            self.nmclient.deactivate_connection(active_conn)
+        self.assertEventually(lambda: self.nmclient.get_active_connections() == [],
+                              timeout=20)
+
+        # verify that NM properly deconfigures the devices
+        self.assert_iface_down(self.dev_w_client)
+        self.assert_iface_down(self.dev_e_client)
+
+    @classmethod
+    def process_glib_events(klass):
+        '''Process pending GLib main loop events'''
+
+        context = GLib.MainContext.default()
+        while context.iteration(False):
+            pass
+
+    def assertEventually(self, condition, message=None, timeout=50):
+        '''Assert that condition function eventually returns True.
+
+        timeout is in deciseconds, defaulting to 50 (5 seconds). message is
+        printed on failure.
+        '''
+        while timeout >= 0:
+            self.process_glib_events()
+            if condition():
+                break
+            timeout -= 1
+            time.sleep(0.1)
+        else:
+            self.fail(message or 'timed out waiting for ' + str(condition))
+
+    def assert_iface_down(self, iface):
+        '''Assert that client interface is down'''
+
+        out = subprocess.check_output(['ip', 'a', 'show', 'dev', iface],
+                                      universal_newlines=True)
+        self.assertNotIn('inet 192', out)
+        self.assertNotIn('inet6 2600', out)
+
+        if iface == self.dev_w_client:
+            out = subprocess.check_output(['iw', 'dev', iface, 'link'],
+                                          universal_newlines=True)
+            self.assertIn('Not connected', out)
+
+            # but AP device should never be touched by NM
+            out = subprocess.check_output(['ip', 'a', 'show', 'dev', self.dev_w_ap],
+                                          universal_newlines=True)
+            self.assertIn('state UP', out)
+
+    def assert_iface_up(self, iface, expected_ip_a=None, unexpected_ip_a=None):
+        '''Assert that client interface is up'''
+
+        out = subprocess.check_output(['ip', 'a', 'show', 'dev', iface],
+                                      universal_newlines=True)
+        self.assertIn('state UP', out)
+        if expected_ip_a:
+            for r in expected_ip_a:
+                self.assertRegex(out, r)
+        if unexpected_ip_a:
+            for r in unexpected_ip_a:
+                self.assertNotRegex(out, r)
+
+        if iface == self.dev_w_client:
+            out = subprocess.check_output(['iw', 'dev', iface, 'link'],
+                                          universal_newlines=True)
+            self.assertIn('Connected to ' + self.mac_w_ap, out)
+            self.assertIn('SSID: ' + SSID, out)
+
+    def wait_ap(self, timeout):
+        '''Wait for AccessPoint NM object to appear, and return it'''
+
+        self.assertEventually(lambda: len(self.nmdev_w.get_access_points()) > 0,
+                              'timed out waiting for AP to be detected',
+                              timeout=timeout)
+
+        return self.nmdev_w.get_access_points()[0]
+
+    def connect_to_ap(self, ap, secret, ipv6_mode, ip6_privacy):
+        '''Connect to an NMAccessPoint.
+
+        secret should be None for open networks, and a string with the password
+        for WEP/WPA.
+
+        ip6_privacy is a NM.SettingIP6ConfigPrivacy flag.
+
+        Return (NMConnection, NMActiveConnection) objects.
+        '''
+
+        ip4_method = NM.SETTING_IP4_CONFIG_METHOD_DISABLED
+        ip6_method = NM.SETTING_IP6_CONFIG_METHOD_IGNORE
+        if ipv6_mode is None:
+            ip4_method = NM.SETTING_IP4_CONFIG_METHOD_AUTO
+        else:
+            ip6_method = NM.SETTING_IP6_CONFIG_METHOD_AUTO
+
+        # If we have a secret, supply it to the new connection right away;
+        # adding it afterwards with update_secrets() does not work, and we
+        # can't implement a SecretAgent as get_secrets() would need to build a
+        # map of a map of gpointers to gpointers which is too much for PyGI
+        partial_conn = NM.SimpleConnection.new()
+        partial_conn.add_setting(NM.SettingIP4Config(method=ip4_method))
+        if secret:
+            partial_conn.add_setting(NM.SettingWirelessSecurity.new())
+            # FIXME: needs update for other auth types
+            partial_conn.update_secrets(NM.SETTING_WIRELESS_SECURITY_SETTING_NAME,
+                                        GLib.Variant('a{sv}', {
+                                            'psk': GLib.Variant('s', secret) 
+                                        }))
+        if ip6_privacy is not None:
+            partial_conn.add_setting(NM.SettingIP6Config(ip6_privacy=ip6_privacy,
+                                                                     method=ip6_method))
+
+        ml = GLib.MainLoop()
+        self.cb_conn = None
+        self.cancel = Gio.Cancellable()
+        self.timeout_tag = 0
+
+        def add_activate_cb(client, res, data):
+            if (self.timeout_tag > 0):
+                GLib.source_remove(self.timeout_tag)
+                self.timeout_tag = 0
+            try:
+                self.cb_conn = \
+                    self.nmclient.add_and_activate_connection_finish(res)
+            except gi.repository.GLib.Error as e:
+                # Check if the error is "Operation was cancelled"
+                if (e.domain != "g-io-error-quark" or e.code != 19):
+                    self.fail("add_and_activate_connection failed: %s (%s, %d)" %
+                              (e.message, e.domain, e.code))
+            ml.quit()
+
+        def timeout_cb():
+            self.timeout_tag = -1
+            self.cancel.cancel()
+            ml.quit()
+            return GLib.SOURCE_REMOVE
+
+        self.nmclient.add_and_activate_connection_async(partial_conn, self.nmdev_w, ap.get_path(), self.cancel, add_activate_cb, None)
+        self.timeout_tag = GLib.timeout_add_seconds(300, timeout_cb)
+        ml.run()
+        if (self.timeout_tag < 0):
+            self.timeout_tag = 0
+            self.fail('Main loop for adding connection timed out!')
+        self.assertNotEqual(self.cb_conn, None)
+        active_conn = self.cb_conn
+        self.cb_conn = None
+
+        conn = self.conn_from_active_conn(active_conn)
+        self.assertTrue(conn.verify())
+
+        # verify need_secrets()
+        needed_secrets = conn.need_secrets()
+        if secret is None:
+            self.assertEqual(needed_secrets, (None, []))
+        else:
+            self.assertEqual(needed_secrets[0], NM.SETTING_WIRELESS_SECURITY_SETTING_NAME)
+            self.assertEqual(type(needed_secrets[1]), list)
+            self.assertGreaterEqual(len(needed_secrets[1]), 1)
+            # FIXME: needs update for other auth types
+            self.assertIn(needed_secrets[1][0], [NM.SETTING_WIRELESS_SECURITY_PSK])
+
+        # we are usually ACTIVATING at this point; wait for completion
+        # TODO: 5s is not enough, argh slow DHCP client
+        self.assertEventually(lambda: active_conn.get_state() == NM.ActiveConnectionState.ACTIVATED,
+                              'timed out waiting for %s to get activated' % active_conn.get_connection(),
+                              timeout=600)
+        self.assertEqual(self.nmdev_w.get_state(), NM.DeviceState.ACTIVATED)
+        return (conn, active_conn)
+
+    def conn_from_active_conn(self, active_conn):
+        '''Get NMConnection object for an NMActiveConnection object'''
+
+        # this sometimes takes a second try, when the corresponding
+        # NMConnection object is not yet available
+        tries = 3
+        while tries > 0:
+            self.process_glib_events()
+            path = active_conn.get_connection().get_path()
+            for dev in active_conn.get_devices():
+                for c in dev.get_available_connections():
+                    if c.get_path() == path:
+                        return c
+            time.sleep(0.1)
+            tries -= 1
+
+        self.fail('Could not find NMConnection object for %s' % path)
+
+    def check_low_level_config(self, iface, ipv6_mode, ip6_privacy):
+        '''Check actual hardware state with ip/iw after being connected'''
+
+        # list of expected regexps in "ip a" output
+        expected_ip_a = []
+        unexpected_ip_a = []
+
+        if ipv6_mode is not None:
+            if ipv6_mode in ('', 'slaac'):
+                # has global address from our DHCP server
+                expected_ip_a.append('inet6 2600::[0-9a-f]+/')
+            else:
+                # has address with our prefix and MAC
+                expected_ip_a.append('inet6 2600::[0-9a-f:]+/64 scope global (?:tentative )?(?:mngtmpaddr )?(?:noprefixroute )?dynamic')
+                # has address with our prefix and random IP (Privacy
+                # Extension), if requested
+                priv_re = 'inet6 2600:[0-9a-f:]+/64 scope global temporary (?:tentative )?(?:mngtmpaddr )?dynamic'
+                if ip6_privacy in (NM.SettingIP6ConfigPrivacy.PREFER_TEMP_ADDR,
+                                   NM.SettingIP6ConfigPrivacy.PREFER_PUBLIC_ADDR):
+                    expected_ip_a.append(priv_re)
+                else:
+                    # FIXME: add a negative test here
+                    pass
+                    #unexpected_ip_a.append(priv_re)
+
+            # has a link-local address
+            expected_ip_a.append('inet6 fe80::[0-9a-f:]+/64 scope link')
+        else:
+            expected_ip_a.append('inet 192.168.5.\d+/24')
+
+        self.assert_iface_up(iface, expected_ip_a, unexpected_ip_a)
+
+
+class ColdplugWifi(NetworkManagerTest):
+    '''Wifi: In these tests NM starts after setting up the AP'''
+
+    # not run by default; run "nm-wifi ColdplugWifi.shell" to get this
+    @network_test_base.run_in_subprocess
+    def shell(self):
+        '''Start AP and NM, then run a shell (for debugging)'''
+
+        self.setup_ap('hw_mode=b\nchannel=1\nssid=' + SSID, None)
+        self.start_nm(self.dev_w_client)
+        print('''
+
+client interface: %s, access point interface: %s, AP SSID: "%s"
+
+You can now run commands like "nmcli dev" or "nmcli dev wifi connect '%s'".
+Logs are in '%s'. When done, exit the shell.
+
+''' % (self.dev_w_client, self.dev_w_ap, SSID, SSID, self.workdir))
+        subprocess.call(['bash', '-i'])
+
+    @network_test_base.run_in_subprocess
+    def test_no_ap(self):
+        '''no available access point'''
+
+        self.start_nm(self.dev_w_client)
+        # Give the interfaces a bit more time to intialized; it may be needed
+        # on ppc64el.
+        time.sleep(30)
+        self.assertEventually(self.nmclient.networking_get_enabled, timeout=20)
+
+        # state independent properties
+        self.assertEqual(self.nmdev_w.props.device_type, NM.DeviceType.WIFI)
+        self.assertTrue(self.nmdev_w.props.managed)
+        self.assertFalse(self.nmdev_w.props.firmware_missing)
+        self.assertTrue(self.nmdev_w.props.udi.startswith('/sys/devices/'), self.nmdev_w.props.udi)
+
+        # get_version() plausibility check
+        out = subprocess.check_output(['nmcli', '--version'], universal_newlines=True)
+        cli_version = out.split()[-1]
+        self.assertTrue(cli_version[0].isdigit())
+        self.assertEqual(self.nmclient.get_version(), cli_version)
+
+        # state dependent properties (disconnected)
+        self.assertIn(self.nmdev_w.get_state(),
+                      [NM.DeviceState.DISCONNECTED, NM.DeviceState.UNAVAILABLE])
+        self.assertEqual(self.nmdev_w.get_access_points(), [])
+        self.assertEqual(self.nmdev_w.get_available_connections(), [])
+
+    def test_open_b_ip4(self):
+        '''Open network, 802.11b, IPv4'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, None, 11000)
+
+    def test_open_b_ip6_raonly_tmpaddr(self):
+        '''Open network, 802.11b, IPv6 with only RA, preferring temp address'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, 'ra-only', 11000,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.PREFER_TEMP_ADDR)
+
+    def test_open_b_ip6_raonly_pubaddr(self):
+        '''Open network, 802.11b, IPv6 with only RA, preferring public address'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, 'ra-only', 11000,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.PREFER_PUBLIC_ADDR)
+
+    def test_open_b_ip6_raonly_no_pe(self):
+        '''Open network, 802.11b, IPv6 with only RA, PE disabled'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, 'ra-only', 11000,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.DISABLED)
+
+    def test_open_b_ip6_dhcp(self):
+        '''Open network, 802.11b, IPv6 with DHCP, preferring temp address'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, '', 11000,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.UNKNOWN)
+
+    def test_open_g_ip4(self):
+        '''Open network, 802.11g, IPv4'''
+
+        self.do_test('hw_mode=g\nchannel=1\nssid=' + SSID, None, 54000)
+
+    def test_wpa1_ip4(self):
+        '''WPA1, 802.11g, IPv4'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=1
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=TKIP
+wpa_passphrase=12345678
+''' % SSID, None, 54000, '12345678')
+
+    def test_wpa2_ip4(self):
+        '''WPA2, 802.11g, IPv4'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+wpa_passphrase=12345678
+''' % SSID, None, 54000, '12345678')
+
+    def test_wpa2_ip6(self):
+        '''WPA2, 802.11g, IPv6 with only RA'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+wpa_passphrase=12345678
+''' % SSID, 'ra-only', 54000, '12345678',
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.PREFER_TEMP_ADDR)
+
+    @network_test_base.run_in_subprocess
+    def test_rfkill(self):
+        '''shut down connection on killswitch, restore it on unblock'''
+
+        self.setup_ap('hw_mode=b\nchannel=1\nssid=' + SSID, None)
+        self.start_nm(self.dev_w_client)
+        ap = self.wait_ap(timeout=1800)
+        (conn, active_conn) = self.connect_to_ap(ap, None, None, None)
+
+        self.assertFalse(self.get_rfkill(self.dev_w_client))
+        self.assertFalse(self.get_rfkill(self.dev_w_ap))
+
+        # now block the client interface
+        self.set_rfkill(self.dev_w_client, True)
+        # disabling should be fast, give it ten seconds
+        self.assertEventually(lambda: self.nmdev_w.get_state() == NM.DeviceState.UNAVAILABLE,
+                              timeout=100)
+
+        # dev_w_client should be down now
+        self.assert_iface_down(self.dev_w_client)
+
+        # turn it back on
+        self.set_rfkill(self.dev_w_client, False)
+        # this involves DHCP, use same timeout as for regular connection
+        self.assertEventually(lambda: self.nmdev_w.get_state() == NM.DeviceState.ACTIVATED,
+                              timeout=200)
+
+        # dev_w_client should be back up
+        self.assert_iface_up(self.dev_w_client, ['inet 192.168.5.\d+/24'])
+
+    #
+    # Common test code
+    #
+
+    # libnm-glib has a lot of internal persistent state (private D-BUS
+    # connections and such); as it is very brittle and hard to track down
+    # all remaining references to any NM* object after a test, we rather
+    # run each test in a separate subprocess
+    @network_test_base.run_in_subprocess
+    def do_test(self, hostapd_conf, ipv6_mode, expected_max_bitrate,
+                secret=None, ip6_privacy=None):
+        '''Actual test code, parameterized for the particular test case'''
+
+        self.setup_ap(hostapd_conf, ipv6_mode)
+        self.start_nm(self.dev_w_client)
+
+        # on coldplug we expect the AP to be picked out fast
+        ap = self.wait_ap(timeout=100)
+        self.assertTrue(ap.get_path().startswith('/org/freedesktop/NetworkManager'))
+        self.assertEqual(ap.get_mode(), getattr(NM, '80211Mode').INFRA)
+        self.assertEqual(ap.get_max_bitrate(), expected_max_bitrate)
+        #self.assertEqual(ap.get_flags(), )
+
+        # should not auto-connect
+        self.assertEqual(self.nmclient.get_active_connections(), [])
+
+        # connect to that AP
+        (conn, active_conn) = self.connect_to_ap(ap, secret, ipv6_mode, ip6_privacy)
+
+        # check NMActiveConnection object
+        self.assertIn(active_conn.get_uuid(), [c.get_uuid() for c in self.nmclient.get_active_connections()])
+        self.assertEqual([d.get_udi() for d in active_conn.get_devices()], [self.nmdev_w.get_udi()])
+
+        # check corresponding NMConnection object
+        wireless_setting = conn.get_setting_wireless()
+        self.assertEqual(wireless_setting.get_ssid().get_data(), SSID.encode())
+        self.assertEqual(wireless_setting.get_hidden(), False)
+        if secret:
+            self.assertEqual(conn.get_setting_wireless_security().get_name(), NM.SETTING_WIRELESS_SECURITY_SETTING_NAME)
+        else:
+            self.assertEqual(conn.get_setting_wireless_security(), None)
+        # for debugging
+        #conn.dump()
+
+        # for IPv6, check privacy setting
+        if ipv6_mode is not None and ip6_privacy != NM.SettingIP6ConfigPrivacy.UNKNOWN:
+            assert ip6_privacy is not None, 'for IPv6 tests you need to specify ip6_privacy flag'
+            ip6_setting = conn.get_setting_ip6_config()
+            self.assertEqual(ip6_setting.props.ip6_privacy, ip6_privacy)
+
+        self.check_low_level_config(self.dev_w_client, ipv6_mode, ip6_privacy)
+
+
+class ColdplugEthernet(NetworkManagerTest):
+    '''Ethernet: In these tests NM starts after setting up the router'''
+
+    # not run by default; run "nm-wifi ColdplugEthernet.shell" to get this
+    @network_test_base.run_in_subprocess
+    def shell(self):
+        '''Start router and NM, then run a shell (for debugging)'''
+
+        self.setup_eth(None)
+        self.start_nm(self.dev_e_client)
+        print('''
+
+client interface: %s, router interface: %s
+
+You can now run commands like "nmcli dev".
+Logs are in '%s'. When done, exit the shell.
+
+''' % (self.dev_e_client, self.dev_e_ap, self.workdir))
+        subprocess.call(['bash', '-i'])
+
+    def test_auto_ip4(self):
+        '''ethernet: auto-connection, IPv4'''
+
+        self.do_test(None, auto_connect=True)
+
+    def test_auto_ip6_raonly_no_pe(self):
+        '''ethernet: auto-connection, IPv6 with only RA, PE disabled'''
+
+        self.do_test('ra-only', auto_connect=True,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.DISABLED)
+
+    def test_auto_ip6_dhcp(self):
+        '''ethernet: auto-connection, IPv6 with DHCP'''
+
+        self.do_test('', auto_connect=True,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.UNKNOWN)
+
+    def test_manual_ip4(self):
+        '''ethernet: manual connection, IPv4'''
+
+        self.do_test(None, auto_connect=False)
+
+    def test_manual_ip6_raonly_tmpaddr(self):
+        '''ethernet: manual connection, IPv6 with only RA, preferring temp address'''
+
+        self.do_test('ra-only', auto_connect=False,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.PREFER_TEMP_ADDR)
+
+    def test_manual_ip6_raonly_pubaddr(self):
+        '''ethernet: manual connection, IPv6 with only RA, preferring public address'''
+
+        self.do_test('ra-only', auto_connect=False,
+                     ip6_privacy=NM.SettingIP6ConfigPrivacy.PREFER_PUBLIC_ADDR)
+
+    #
+    # Common test code
+    #
+
+    @network_test_base.run_in_subprocess
+    def do_test(self, ipv6_mode, ip6_privacy=None, auto_connect=True):
+        '''Actual test code, parameterized for the particular test case'''
+
+        self.setup_eth(ipv6_mode)
+        self.start_nm(self.dev_e_client, auto_connect=auto_connect)
+
+        ip4_method = NM.SETTING_IP4_CONFIG_METHOD_DISABLED
+        ip6_method = NM.SETTING_IP6_CONFIG_METHOD_IGNORE
+        if ipv6_mode is None:
+            ip4_method = NM.SETTING_IP4_CONFIG_METHOD_AUTO
+        else:
+            ip6_method = NM.SETTING_IP6_CONFIG_METHOD_AUTO
+
+        if auto_connect:
+            # ethernet should auto-connect quickly without an existing defined connection
+            self.assertEventually(lambda: len(self.nmclient.get_active_connections()) > 0,
+                                  'timed out waiting for active connections',
+                                  timeout=100)
+            active_conn = self.nmclient.get_active_connections()[0]
+        else:
+            # auto-connection was disabled, set up manual connection
+            partial_conn = NM.SimpleConnection.new()
+            partial_conn.add_setting(NM.SettingIP4Config(method=ip4_method))
+            if ip6_privacy is not None:
+                partial_conn.add_setting(NM.SettingIP6Config(ip6_privacy=ip6_privacy,
+                                                                         method=ip6_method))
+
+            ml = GLib.MainLoop()
+            self.cb_conn = None
+            self.cancel = Gio.Cancellable()
+            self.timeout_tag = 0
+
+            def add_activate_cb(client, res, data):
+                if (self.timeout_tag > 0):
+                    GLib.source_remove(self.timeout_tag)
+                    self.timeout_tag = 0
+                try:
+                    self.cb_conn = \
+                        self.nmclient.add_and_activate_connection_finish(res)
+                except gi.repository.GLib.Error as e:
+                    # Check if the error is "Operation was cancelled"
+                    if (e.domain != "g-io-error-quark" or e.code != 19):
+                        self.fail("add_and_activate_connection failed: %s (%s, %d)" %
+                                  (e.message, e.domain, e.code))
+                ml.quit()
+
+            def timeout_cb():
+                self.timeout_tag = -1
+                self.cancel.cancel()
+                ml.quit()
+                return GLib.SOURCE_REMOVE
+
+            self.nmclient.add_and_activate_connection_async(partial_conn, self.nmdev_e, None, self.cancel, add_activate_cb, None)
+            self.timeout_tag = GLib.timeout_add_seconds(300, timeout_cb)
+            ml.run()
+            if (self.timeout_tag < 0):
+                self.timeout_tag = 0
+                self.fail('Main loop for adding connection timed out!')
+            self.assertNotEqual(self.cb_conn, None)
+            active_conn = self.cb_conn
+            self.cb_conn = None
+
+        # we are usually ACTIVATING at this point; wait for completion
+        # TODO: 5s is not enough, argh slow DHCP client
+        self.assertEventually(lambda: active_conn.get_state() == NM.ActiveConnectionState.ACTIVATED,
+                              'timed out waiting for %s to get activated' % active_conn.get_connection(),
+                              timeout=150)
+        self.assertEqual(self.nmdev_e.get_state(), NM.DeviceState.ACTIVATED)
+
+        conn = self.conn_from_active_conn(active_conn)
+        self.assertTrue(conn.verify())
+
+        # check NMActiveConnection object
+        self.assertIn(active_conn.get_uuid(), [c.get_uuid() for c in self.nmclient.get_active_connections()])
+        self.assertEqual([d.get_udi() for d in active_conn.get_devices()], [self.nmdev_e.get_udi()])
+
+        # for IPv6, check privacy setting
+        if ipv6_mode is not None:
+            assert ip6_privacy is not None, 'for IPv6 tests you need to specify ip6_privacy flag'
+            if ip6_privacy not in (NM.SettingIP6ConfigPrivacy.UNKNOWN,
+                                   NM.SettingIP6ConfigPrivacy.DISABLED):
+                ip6_setting = conn.get_setting_ip6_config()
+                self.assertEqual(ip6_setting.props.ip6_privacy, ip6_privacy)
+
+        self.check_low_level_config(self.dev_e_client, ipv6_mode, ip6_privacy)
+
+
+class Hotplug(NetworkManagerTest):
+    '''In these tests APs are set up while NM is already running'''
+
+    @network_test_base.run_in_subprocess
+    @unittest.expectedFailure
+    def test_auto_detect_ap(self):
+        '''new AP is being detected automatically within 30s'''
+
+        self.setup_ap('hw_mode=b\nchannel=1\nssid=' + SSID, None)
+        self.start_nm()
+        ap = self.wait_ap(timeout=300)
+        # get_ssid returns a byte array
+        self.assertEqual(ap.get_ssid(), SSID.encode())
+        self.assertEqual(self.nmdev_w.get_active_access_point(), None)
+
+    @network_test_base.run_in_subprocess
+    @unittest.expectedFailure
+    def test_auto_detect_eth(self):
+        '''new eth router is being detected automatically within 30s'''
+
+        self.start_nm()
+        self.setup_eth(None)
+        self.assertEventually(lambda: len(self.nmclient.get_active_connections()) > 0,
+                              timeout=300)
+        active_conn = self.nmclient.get_active_connections()[0]
+
+        self.assertEventually(lambda: active_conn.get_state() == NM.ActiveConnectionState.ACTIVATED,
+                              'timed out waiting for %s to get activated' % active_conn.get_connection(),
+                              timeout=80)
+        self.assertEqual(self.nmdev_e.get_state(), NM.DeviceState.ACTIVATED)
+
+        conn = self.conn_from_active_conn(active_conn)
+        self.assertTrue(conn.verify())
+
+
+@unittest.skipIf(DBusTestCase is object,
+                 'WARNING: python-dbusmock not installed, skipping suspend tests; get it from https://pypi.python.org/pypi/python-dbusmock')
+class Suspend(NetworkManagerTest, DBusTestCase):
+    '''These tests run under a mock logind on a private system D-BUS'''
+
+    @classmethod
+    def setUpClass(klass):
+        klass.start_system_bus()
+        NetworkManagerTest.setUpClass()
+
+    @classmethod
+    def tearDownClass(klass):
+        NetworkManagerTest.tearDownClass()
+        DBusTestCase.tearDownClass()
+
+    def setUp(self):
+        NetworkManagerTest.setUp(self)
+
+        # start mock polkit and logind processes, so that we can
+        # intercept/control suspend
+        (p_polkit, self.obj_polkit) = self.spawn_server_template('polkitd', {}, stdout=subprocess.PIPE)
+        # by default we are not concerned about restricting access in the tests
+        self.obj_polkit.AllowUnknown(True)
+        self.addCleanup(p_polkit.wait)
+        self.addCleanup(p_polkit.terminate)
+
+        (p_logind, self.obj_logind) = self.spawn_server_template('logind', {}, stdout=subprocess.PIPE)
+        self.addCleanup(p_logind.wait)
+        self.addCleanup(p_logind.terminate)
+
+        # we have to manually start wpa_supplicant, as D-BUS activation does
+        # not happen for the fake D-BUS
+        log = os.path.join(self.workdir, 'wpasupplicant.log')
+        p_wpasupp = subprocess.Popen(['wpa_supplicant', '-u', '-d', '-e', '-K',
+                                      self.entropy_file, '-f', log])
+        self.addCleanup(p_wpasupp.wait)
+        self.addCleanup(p_wpasupp.terminate)
+
+    def fixme_test_active_ip4(self):
+        '''suspend during active IPv4 connection'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, None,
+                     ['inet 192.168.5.\d+/24'])
+
+    def fixme_test_active_ip6(self):
+        '''suspend during active IPv6 connection'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID, 'ra-only',
+                     ['inet6 2600::'])
+
+    #
+    # Common test code
+    #
+
+    @network_test_base.run_in_subprocess
+    def do_test(self, hostapd_conf, ipv6_mode, expected_ip_a):
+        '''Actual test code, parameterized for the particular test case'''
+
+        self.setup_ap(hostapd_conf, ipv6_mode)
+        self.start_nm(self.dev_w_client)
+        ap = self.wait_ap(timeout=1800)
+        (conn, active_conn) = self.connect_to_ap(ap, None, ipv6_mode, None)
+
+        # send logind signal that we are about to suspend
+        self.obj_logind.EmitSignal('', 'PrepareForSleep', 'b', [True])
+
+        # disabling should be fast, give it one second
+        self.assertEventually(lambda: self.nmdev_w.get_state() == NM.DeviceState.UNMANAGED,
+                              timeout=10)
+        self.assert_iface_down(self.dev_w_client)
+
+        # send logind signal that we resumed
+        self.obj_logind.EmitSignal('', 'PrepareForSleep', 'b', [False])
+
+        # this involves DHCP, use same timeout as for regular connection
+        self.assertEventually(lambda: self.nmdev_w.get_state() == NM.DeviceState.ACTIVATED,
+                              timeout=100)
+
+        # dev_w_client should be back up
+        self.assert_iface_up(self.dev_w_client, expected_ip_a)
+
+
+def setUpModule():
+    # AppArmor currently does not allow us to access the system D-BUS from an
+    # unshared file system. Hack the policy to allow that until that gets fixed
+    # properly. See https://launchpad.net/bugs/1244157
+    subprocess.check_call("sed '/nm-dhcp-client.action {/ s/{/flags=(attach_disconnected) {/'"
+                          " /etc/apparmor.d/sbin.dhclient > $ADTTMP/sbin.dhclient",
+                          shell=True)
+    subprocess.check_call('apparmor_parser -Kr $ADTTMP/sbin.dhclient', shell=True)
+
+    # unshare the mount namespace, so that our tmpfs mounts are guaranteed to get
+    # cleaned up, and don't influence the production system
+    libc6 = ctypes.cdll.LoadLibrary('libc.so.6')
+    assert libc6.unshare(ctypes.c_int(0x00020000)) == 0, 'failed to unshare mount namespace'
+
+    # stop system-wide NetworkManager to avoid interfering with tests
+    nm_running = subprocess.call('service NetworkManager stop 2>&1', shell=True) == 0
+
+
+def tearDownModule():
+    subprocess.call('dhclient eth0', shell=True)
+    subprocess.call('sleep 10', shell=True)
+
+
+if __name__ == '__main__':
+    # avoid unintelligible error messages, and breaking "make check" when not being
+    # root
+    if os.getuid() != 0:
+        sys.stderr.write('This integration test suite needs to be run as root\n')
+        sys.exit(1)
+
+    if re.search(b's390', subprocess.run(['dpkg', '--print-architecture'], capture_output=True).stdout):
+        print("s390 arch has no wireless support, skipping")
+        sys.exit(77)
+
+    # write to stdout, not stderr
+    runner = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
+    unittest.main(testRunner=runner)
diff -pruN 1.26.2-1/debian/tests/urfkill-integration 1.26.2-1ubuntu1/debian/tests/urfkill-integration
--- 1.26.2-1/debian/tests/urfkill-integration	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/urfkill-integration	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+if dpkg --print-architecture | grep s390; then
+    echo "Skipping rfkill tests on s390 (LP: #1855009)"
+    exit 77
+fi
+
+if dpkg --print-architecture | grep i386; then
+    echo "Skipping rfkill tests on i386 (LP: #1855183)"
+    exit 77
+fi
+
+set -e
+
+echo "+++ Building / adding fake-rfkill.ko"
+make -f debian/tests/Makefile fake-rfkill
+# poor man's dependency resolver
+DEPS=$(modinfo debian/tests/fake-rfkill.ko | sed -n '/depends:/ {s/^.*://; s/[[:space:]]*$//; p}')
+[ -z "$DEPS" ] || modprobe "$DEPS"
+insmod debian/tests/fake-rfkill.ko
+
+fake_id=$(rfkill list | grep fake | awk -F: '{ print $1; }')
+echo "+++ fake-rfkill.ko is device $fake_id"
+echo
+
+
+echo "--- Testing killswitch bringup to match NM state: when URFKILL doesn't run"
+echo "+++ stopping urfkill"
+# ignore failure, only here, because urfkill probably isn't running yet.
+service urfkill stop || true
+echo "+++ unblocking device $fake_id"
+rfkill unblock $fake_id
+echo "+++ stopping network-manager"
+service NetworkManager stop || true
+echo "+++ blocking device $fake_id"
+rfkill block $fake_id
+echo "+++ starting network-manager"
+service NetworkManager start
+
+echo "+++ Waiting for the devices to settle"
+sleep 30
+
+echo -n "=== NetworkManager state should now be \"enabled\": "
+LC_MESSAGES=C nmcli radio wifi
+LC_MESSAGES=C nmcli radio wifi | grep -qc enabled
+echo
+
+echo -n "=== NM saved state: "
+grep WirelessEnabled /var/lib/NetworkManager/NetworkManager.state
+grep -qc WirelessEnabled=true /var/lib/NetworkManager/NetworkManager.state
+echo
+echo
+
+echo "--- Testing killswitch bringup when URFKILL is running: follow URfkill signals"
+echo "+++ starting urfkill"
+service urfkill start
+sleep 15
+echo "+++ blocking device $fake_id"
+rfkill block $fake_id
+rfkill list
+
+echo "+++ Waiting for the devices to settle"
+sleep 30
+
+echo -n "=== NetworkManager state should now be \"disabled\": "
+LC_MESSAGES=C nmcli radio wifi
+LC_MESSAGES=C nmcli radio wifi | grep -qc disabled
+echo
+
+echo -n "=== NM saved state: "
+grep WirelessEnabled /var/lib/NetworkManager/NetworkManager.state
+#grep -qc WirelessEnabled=false /var/lib/NetworkManager/NetworkManager.state
+echo
+echo
+
+echo "+++ Asking urfkill to unblock device $fake_id"
+dbus-send --print-reply --system --dest=org.freedesktop.URfkill /org/freedesktop/URfkill org.freedesktop.URfkill.BlockIdx uint32:$fake_id boolean:false
+sleep 5
+echo -n "=== NetworkManager state should now be \"enabled\": "
+LC_MESSAGES=C nmcli radio wifi
+LC_MESSAGES=C nmcli radio wifi | grep -qc enabled
+echo
+
+echo "+++ Asking urfkill to block device $fake_id again"
+dbus-send --print-reply --system --dest=org.freedesktop.URfkill /org/freedesktop/URfkill org.freedesktop.URfkill.BlockIdx uint32:$fake_id boolean:true
+sleep 5
+echo -n "=== NetworkManager state should now be \"disabled\": "
+LC_MESSAGES=C nmcli radio wifi
+LC_MESSAGES=C nmcli radio wifi | grep -qc disabled
+echo
+echo
+
+echo "--- Removing fake-rfkill, aggregate state should get back to enabled"
+rmmod fake-rfkill
+sleep 5
+echo -n "=== Checking that the fake device $fake_id has disappeared: "
+rfkill list | ( ! grep -qc fake || exit 1 ) && echo yes || echo no
+
+echo -n "=== NetworkManager state should now be \"enabled\": "
+LC_MESSAGES=C nmcli radio wifi
+LC_MESSAGES=C nmcli radio wifi | grep -qc enabled
+echo
+
+#cleanup
+make -f debian/tests/Makefile clean-rfkill
+
+echo OK
+exit 0
diff -pruN 1.26.2-1/debian/tests/wpa-dhclient 1.26.2-1ubuntu1/debian/tests/wpa-dhclient
--- 1.26.2-1/debian/tests/wpa-dhclient	1970-01-01 00:00:00.000000000 +0000
+++ 1.26.2-1ubuntu1/debian/tests/wpa-dhclient	2020-08-31 09:09:40.000000000 +0000
@@ -0,0 +1,244 @@
+#!/usr/bin/python3
+# Test wpa_supplicant and dhclient in various modes
+
+__author__ = 'Martin Pitt <martin.pitt@ubuntu.com>'
+__copyright__ = '(C) 2013 Canonical Ltd.'
+__license__ = 'GPL v2 or later'
+
+import sys
+import os
+import os.path
+import re
+import time
+import subprocess
+import unittest
+
+sys.path.append(os.path.dirname(__file__))
+import network_test_base
+
+SSID = 'fake net'
+
+
+class T(network_test_base.NetworkTestBase):
+    @unittest.expectedFailure
+    def test_open_a_ip4(self):
+        '''Open network, 802.11a, IPv4'''
+
+        # channel 36 ought to work everywhere
+        self.do_test('hw_mode=a\nchannel=36\n\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     None,
+                     ['54.0'])
+
+    @unittest.expectedFailure
+    def test_open_a_ip6(self):
+        '''Open network, 802.11a, IPv6'''
+
+        self.do_test('hw_mode=a\nchannel=36\n\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     '',
+                     ['54.0'])
+
+    def test_open_b_ip4(self):
+        '''Open network, 802.11b, IPv4'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     None,
+                     ['11.0'])
+
+    def test_open_b_ip6_dhcp(self):
+        '''Open network, 802.11b, IPv6 with DHCP'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     '',
+                     ['11.0'])
+
+    def test_open_b_ip6_raonly(self):
+        '''Open network, 802.11b, IPv6 with only RA'''
+
+        self.do_test('hw_mode=b\nchannel=1\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     'ra-only',
+                     ['11.0'])
+
+    def test_open_g_ip4(self):
+        '''Open network, 802.11g, IPv4'''
+
+        self.do_test('hw_mode=g\nchannel=1\nssid=' + SSID,
+                     'ssid="%s"\nkey_mgmt=NONE' % SSID,
+                     None,
+                     ['54.0'])
+
+    def test_wpa1_ip4(self):
+        '''WPA1, 802.11g, IPv4'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=1
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=TKIP
+wpa_passphrase=12345678
+''' % SSID,
+                     '''ssid="%s"
+psk="12345678"
+key_mgmt=WPA-PSK
+proto=WPA
+pairwise=TKIP
+group=TKIP''' % SSID,
+                     None,
+                     ['54.0',
+                      'Pairwise ciphers: TKIP',
+                      'Authentication suites: PSK'])
+
+    def test_wpa2_ip4(self):
+        '''WPA2, 802.11g, IPv4'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+wpa_passphrase=12345678
+''' % SSID,
+                     '''ssid="%s"
+psk="12345678"
+key_mgmt=WPA-PSK
+proto=WPA2
+pairwise=CCMP
+group=CCMP''' % SSID,
+                     None,
+                     ['54.0',
+                      'Pairwise ciphers: CCMP',
+                      'Authentication suites: PSK'])
+
+    def test_wpa2_ip6(self):
+        '''WPA2, 802.11g, IPv6'''
+
+        self.do_test('''hw_mode=g
+channel=1
+ssid=%s
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+wpa_passphrase=12345678
+''' % SSID,
+                     '''ssid="%s"
+psk="12345678"
+key_mgmt=WPA-PSK
+proto=WPA2
+pairwise=CCMP
+group=CCMP''' % SSID,
+                     '',
+                     ['54.0',
+                      'Pairwise ciphers: CCMP',
+                      'Authentication suites: PSK'])
+
+    #
+    # Common for all tests
+    #
+
+    def do_test(self, hostapd_conf, wpa_conf, ipv6, exp_iw_scan):
+        self.setup_ap(hostapd_conf, ipv6)
+        self.check_ssid_avail(exp_iw_scan)
+        self.start_wpasupp(wpa_conf)
+        self.check_iw_link()
+        self.check_communication(ipv6)
+        self.check_address(ipv6)
+
+    def check_ssid_avail(self, expected_strings):
+        subprocess.check_call(['ip', 'link', 'set', self.dev_w_client, 'up'])
+        out = subprocess.check_output(['iw', 'dev', self.dev_w_client, 'scan'],
+                                      universal_newlines=True)
+        # down it again, wpa_supplicant is supposed to up it by itself
+        subprocess.check_call(['ip', 'link', 'set', self.dev_w_client, 'down'])
+
+        self.assertRegex(out, 'SSID: ' + SSID)
+        for s in expected_strings:
+            self.assertRegex(out, s)
+
+    def check_iw_link(self):
+        tries = 10
+        while tries > 0:
+            out = subprocess.check_output(['iw', 'dev', self.dev_w_client, 'link'],
+                                          universal_newlines=True)
+            if 'SSID' in out:
+                break
+            tries -= 1
+            time.sleep(1)
+        else:
+            self.fail('timed out on iwconfig showing connected status')
+
+        self.assertRegex(out, 'Connected to ' + self.mac_w_ap)
+        self.assertRegex(out, 'SSID: ' + SSID)
+
+    def check_communication(self, ipv6_mode):
+        '''Verify that communication works between AP and client
+
+        This proves that wpa_supplicant set up a working link. We use a DHCP
+        request for IPv4 and IPv6 in DHCP mode. For IPv6 in other (i.
+        e. ra-only/slaac) modes, check that dnsmasq received a router solicit
+        and sends a router advertisement.
+        '''
+        if ipv6_mode is not None:
+            self.poll_text(self.dnsmasq_log, 'RTR-SOLICIT(%s)' % self.dev_w_ap, timeout=50)
+            self.poll_text(self.dnsmasq_log, 'RTR-ADVERT(%s)' % self.dev_w_ap, timeout=5)
+
+        # stop here for non-DHCP modes in IPv6
+        if ipv6_mode not in (None, '', 'slaac'):
+            return
+
+        # FIXME: sometimes takes more than 5 s in IPv6 mode
+        if ipv6_mode is not None:
+            mode = '-6'
+            timeout = 10
+        else:
+            mode = '-4'
+            timeout = 5
+
+        # run DHCP client on client
+        out = subprocess.check_output(['dhclient', mode, '-1', '-v',
+                                       '-lf', '/dev/null', self.dev_w_client],
+                                      universal_newlines=True, timeout=timeout,
+                                      stderr=subprocess.STDOUT)
+        # stop DHCP client
+        subprocess.call(['dhclient', '-x', mode, self.dev_w_client],
+                        stderr=subprocess.STDOUT)
+
+        if ipv6_mode is not None:
+            self.assertRegex(out, 'status code Success')
+            self.assertRegex(out, 'IAADDR 2600::')
+        else:
+            self.assertRegex(out, 'DHCPACK of')
+            self.assertRegex(out, 'bound to')
+
+    def check_address(self, ipv6_mode):
+        '''Verify that the interface got an appropriate address assigned'''
+
+        out = subprocess.check_output(['ip', 'a', 'show', 'dev', self.dev_w_client],
+                                      universal_newlines=True)
+        self.assertRegex(out, 'state UP')
+        if ipv6_mode is None:
+            self.assertRegex(out, 'inet 192.168.5.\d+/24')
+        else:
+            if not ipv6_mode:
+                # has global address from our DHCP server
+                self.assertRegex(out, 'inet6 2600::[0-9a-z]+/\d')
+            else:
+                # has address with our prefix and MAC
+                self.assertRegex(out, 'inet6 2600::ff:fe00:[0-9a-z]+/64 scope global (?:tentative )?(?:mngtmpaddr )?dynamic')
+
+            # has a link-local address
+            self.assertRegex(out, 'inet6 fe80::ff:fe00:[0-9a-z:]+/64 scope link')
+
+
+if re.search(b's390', subprocess.run(['dpkg', '--print-architecture'], capture_output=True).stdout):
+    print("s390 arch has no wireless support, skipping")
+    sys.exit(77)
+
+# write to stdout, not stderr
+runner = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
+unittest.main(testRunner=runner)
