summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-10-16 08:47:38 +0200
committerMichael Biebl <biebl@debian.org>2011-10-16 08:47:38 +0200
commitdcc310e31af7fa88eb51fabe90de7edd374aecc5 (patch)
treea517abb10b0f0be34e511ca0cb2a78a2e0074362
parent263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (diff)
Imported Upstream version 0.9.1.90 upstream/0.9.1.90
-rw-r--r--Makefile.in6
-rw-r--r--NEWS108
-rw-r--r--TODO120
-rw-r--r--callouts/Makefile.in6
-rw-r--r--callouts/tests/Makefile.in6
-rw-r--r--cli/Makefile.in6
-rw-r--r--cli/src/Makefile.in6
-rw-r--r--cli/src/connections.c107
-rw-r--r--cli/src/devices.c67
-rw-r--r--cli/src/network-manager.c9
-rw-r--r--cli/src/settings.c221
-rw-r--r--cli/src/utils.c3
-rw-r--r--config.h.in9
-rwxr-xr-xconfigure265
-rw-r--r--configure.ac44
-rw-r--r--data/Makefile.in6
-rw-r--r--docs/Makefile.in6
-rw-r--r--docs/api/Makefile.in6
-rw-r--r--docs/api/html/NetworkManager.devhelp28
-rw-r--r--docs/api/html/NetworkManager.devhelp228
-rw-r--r--docs/api/html/index.html32
-rw-r--r--docs/api/html/ix01.html2
-rw-r--r--docs/api/html/ref-migrating.html58
-rw-r--r--docs/api/html/ref-settings.html36
-rw-r--r--docs/api/html/spec.html132
-rw-r--r--docs/api/spec.html132
-rw-r--r--docs/api/version.xml2
-rw-r--r--docs/libnm-glib/Makefile.in6
-rw-r--r--docs/libnm-glib/html/ch02.html2
-rw-r--r--docs/libnm-glib/html/index.html2
-rw-r--r--docs/libnm-util/Makefile.in6
-rw-r--r--docs/libnm-util/html/NMConnection.html59
-rw-r--r--docs/libnm-util/html/NMSetting.html79
-rw-r--r--docs/libnm-util/html/api-index-full.html427
-rw-r--r--docs/libnm-util/html/ch01.html2
-rw-r--r--docs/libnm-util/html/index.sgml4
-rw-r--r--docs/libnm-util/html/libnm-util.devhelp4
-rw-r--r--docs/libnm-util/html/libnm-util.devhelp24
-rw-r--r--docs/libnm-util/libnm-util-sections.txt3
-rw-r--r--examples/C/Makefile.in6
-rw-r--r--examples/C/glib/Makefile.in6
-rw-r--r--examples/C/qt/Makefile.in6
-rw-r--r--examples/Makefile.in6
-rw-r--r--examples/python/Makefile.am5
-rw-r--r--examples/python/Makefile.in9
-rw-r--r--include/Makefile.in6
-rw-r--r--include/nm-version.h2
-rw-r--r--initscript/Arch/Makefile.in6
-rw-r--r--initscript/Debian/Makefile.in6
-rw-r--r--initscript/Gentoo/Makefile.in6
-rw-r--r--initscript/Makefile.in6
-rw-r--r--initscript/Mandriva/Makefile.in6
-rw-r--r--initscript/RedHat/Makefile.in6
-rw-r--r--initscript/SUSE/Makefile.in6
-rw-r--r--initscript/Slackware/Makefile.in6
-rw-r--r--initscript/linexa/Makefile.in6
-rw-r--r--initscript/paldo/Makefile.in6
-rw-r--r--introspection/Makefile.in6
-rw-r--r--introspection/all.xml.in1
-rw-r--r--libnm-glib/Makefile.in6
-rw-r--r--libnm-glib/tests/Makefile.in6
-rw-r--r--libnm-util/Makefile.am2
-rw-r--r--libnm-util/Makefile.in8
-rw-r--r--libnm-util/libnm-util.ver2
-rw-r--r--libnm-util/nm-connection.c59
-rw-r--r--libnm-util/nm-connection.h4
-rw-r--r--libnm-util/nm-setting-vpn.c25
-rw-r--r--libnm-util/nm-setting.c55
-rw-r--r--libnm-util/nm-setting.h26
-rw-r--r--libnm-util/tests/Makefile.in6
-rw-r--r--libnm-util/tests/certs/Makefile.in6
-rw-r--r--man/Makefile.in6
-rw-r--r--man/nmcli.126
-rw-r--r--man/nmcli.1.in26
-rw-r--r--marshallers/Makefile.in6
-rw-r--r--policy/Makefile.in6
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in46
-rw-r--r--src/NetworkManagerUtils.c4
-rw-r--r--src/backends/Makefile.in6
-rw-r--r--src/backends/NetworkManagerGeneric.c16
-rw-r--r--src/bluez-manager/Makefile.in6
-rw-r--r--src/dhcp-manager/Makefile.in6
-rw-r--r--src/dhcp-manager/tests/Makefile.in6
-rw-r--r--src/dns-manager/Makefile.in6
-rw-r--r--src/dns-manager/nm-dns-bind.c3
-rw-r--r--src/dns-manager/nm-dns-dnsmasq.c68
-rw-r--r--src/dns-manager/nm-dns-manager.c3
-rw-r--r--src/dns-manager/nm-dns-plugin.c6
-rw-r--r--src/dns-manager/nm-dns-plugin.h6
-rw-r--r--src/dnsmasq-manager/Makefile.in6
-rw-r--r--src/ip6-manager/Makefile.in6
-rw-r--r--src/ip6-manager/nm-ip6-manager.c55
-rw-r--r--src/logging/Makefile.in6
-rw-r--r--src/modem-manager/Makefile.in6
-rw-r--r--src/modem-manager/nm-modem.c14
-rw-r--r--src/nm-device-ethernet.c96
-rw-r--r--src/nm-device-olpc-mesh.c6
-rw-r--r--src/nm-device-wifi.c10
-rw-r--r--src/nm-device.c45
-rw-r--r--src/nm-manager.c44
-rw-r--r--src/nm-netlink-compat.c105
-rw-r--r--src/nm-netlink-compat.h198
-rw-r--r--src/nm-netlink-monitor.c90
-rw-r--r--src/nm-netlink-monitor.h4
-rw-r--r--src/nm-netlink-utils.c423
-rw-r--r--src/nm-netlink-utils.h80
-rw-r--r--src/nm-policy.c16
-rw-r--r--src/nm-system.c901
-rw-r--r--src/nm-system.h35
-rw-r--r--src/nm-wifi-ap.c91
-rw-r--r--src/nm-wifi-ap.h7
-rw-r--r--src/ppp-manager/Makefile.in6
-rw-r--r--src/ppp-manager/nm-ppp-manager.c2
-rw-r--r--src/settings/Makefile.in6
-rw-r--r--src/settings/nm-settings-connection.c288
-rw-r--r--src/settings/plugins/Makefile.in6
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.in6
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c6
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.in6
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in6
-rw-r--r--src/settings/plugins/ifcfg-suse/Makefile.in6
-rw-r--r--src/settings/plugins/ifnet/Makefile.in6
-rw-r--r--src/settings/plugins/ifnet/connection_parser.c18
-rw-r--r--src/settings/plugins/ifnet/tests/Makefile.in6
-rw-r--r--src/settings/plugins/ifnet/tests/net2
-rw-r--r--src/settings/plugins/ifnet/tests/test_all.c48
-rw-r--r--src/settings/plugins/ifnet/tests/wpa_supplicant.conf3
-rw-r--r--src/settings/plugins/ifupdown/Makefile.in6
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.in6
-rw-r--r--src/settings/plugins/keyfile/Makefile.in6
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.in6
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.in6
-rw-r--r--src/settings/plugins/keyfile/writer.c24
-rw-r--r--src/settings/tests/Makefile.in6
-rw-r--r--src/supplicant-manager/Makefile.in6
-rw-r--r--src/supplicant-manager/nm-supplicant-config.c2
-rw-r--r--src/supplicant-manager/tests/Makefile.in6
-rw-r--r--src/tests/Makefile.in6
-rw-r--r--src/vpn-manager/Makefile.in6
-rw-r--r--src/vpn-manager/nm-vpn-connection.c34
-rw-r--r--src/vpn-manager/nm-vpn-connection.h1
-rw-r--r--src/vpn-manager/nm-vpn-manager.c21
-rw-r--r--src/vpn-manager/nm-vpn-manager.h7
-rw-r--r--src/wimax/Makefile.in6
-rw-r--r--src/wimax/nm-device-wimax.c94
-rw-r--r--test/Makefile.in6
-rw-r--r--tools/Makefile.in6
148 files changed, 3654 insertions, 1895 deletions
diff --git a/Makefile.in b/Makefile.in
index da04d938..e092bfdc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -235,6 +235,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/NEWS b/NEWS
index b27a9b2e..dbcbc121 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,112 @@
 ==============================================
+NetworkManager-0.9.2
+Overview of changes since NetworkManager-0.9.0
+==============================================
+
+* Support for libnl2 and libnl3 and various leak fixes
+* Various small bug fixes in the ifnet config plugin
+* Ensure IPv6 link-local DNS servers work correctly in the dnsmasq DNS plugin
+* Add ability for nmcli to delete connections
+* Fix setup of connection sharing with newer iptables versions
+* Ensure WiMAX activation emits correct signals (fixes initial signal strength)
+* Fix an issue with duplicated keyfile connections
+* Ensure the 'novj' options is passed through to pppd
+* Store timestamps for VPN connections too
+
+
+==============================================
+NetworkManager-0.9.0
+Overview of changes since NetworkManager-0.8.x
+==============================================
+
+This is a new stable release of NetworkManager.  Notable changes include:
+
+* All connections and configuration now managed by NetworkManager
+* Secrets for any connection can now be stored in user session or by NetworkManager
+* All secrets can now be requested each time
+* Fast User Switching support
+* Support for WiMAX mobile broadband
+* Connections can now be restricted to one or more users
+* Support for 802.1X certificate subject matching for greater security
+* Requires wpa_supplicant 0.7 or later
+* Better support for AP roaming using nl80211 and background scanning
+* Simplified D-Bus API for easier client usage
+* Support for GObject Introspection in libnm-glib and libnm-util
+
+
+==============================================
+NetworkManager-0.8.6
+Overview of changes since NetworkManager-0.8.4
+==============================================
+
+This is a new stable release of NetworkManager.  Notable changes include:
+
+* Fix handling of WINS server address in libnm-glib
+* Fix checks for s390 CTC device types
+* Fix export of nm_device_get_ip_iface() in libnm-glib
+* Fix export of IPv6 DNS GValue conversion functions in libnm-glib
+* Recognize and manage platform 'gadget' devices
+* Send only "short" hostname, not FQDN, to DHCP servers
+* Allow "_" as a valid character for GSM APNs
+* Handle shared connections in the ifnet plugin
+* Fix Ad-Hoc frequency selection for user-created Ad-Hoc networks
+* Allow failed connections to be retried when Ethernet carrier bounces
+* Allow usage of paths for certificates and keys in the keyfile plugin
+* Fix crash requesting system VPN secrets
+* Add ability to blacklist certain MAC addresses for wired & wifi connections
+* Ensure users are authorized to share wifi networks (CVE-2011-2176)
+
+
+==============================================
+NetworkManager-0.8.4
+Overview of changes since NetworkManager-0.8.2
+==============================================
+
+This is a new stable release of NetworkManager.  Notable changes include:
+
+* Preliminary support for Exherbo Linux
+* Logging fixes to suppress unnecessary messages
+* Ensure removed devices are cleaned up
+* Fix potential 64-bit crash updating timestamps
+* IPv6 setup, routing, and compliance fixes
+* Fix WWAN enable/disable handling
+* Handle reverse DNS lookups with local caching nameserver configurations
+* Ensure usable DNS configuration is written when NetworkManager quits
+* No longer updates /etc/hosts when hostname changes
+* Request WPAD option from DHCP servers
+* Allow use of paths for certificates and keys in connection keyfiles
+* Allow operation without any DHCP client installed
+* Fix operation with newer versions of dnsmasq
+* nmcli support for WWAN connections
+* Persistent hostname sent to DHCP servers by default
+* Allow disabing PPP support at build time
+* Red Hat/Fedora ifcfg plugin fixes for handling S390 CTC device configuration
+* Red Hat/Fedora ifcfg plugin fixes for handling IPADDR config items
+* Shutdown crash fixes
+* Memory leak fixes
+* Documentation fixes and updates
+* and much more...
+
+==============================================
+NetworkManager-0.8.2
+Overview of changes since NetworkManager-0.8.1
+==============================================
+
+This is a new stable release of NetworkManager.  Notable changes include:
+
+* Native local caching nameserver support using dnsmasq
+* Automatically detect addition and removal of new VPN plugins
+* Support for handling suspend/resume signals from UPower
+* Ensure users are allowed to enable/disable WiFi and networking
+* Ensure WiFi enable state is perserved across reboot and suspend
+* Better handling of /etc/hosts and preservation of custom hostnames
+* Support for the systemd session management service
+* Better handling of 'keyfile' system connection errors
+* Support for S390 network devices
+* and much more...
+
+
+==============================================
 NetworkManager-0.7.0
 Overview of changes since NetworkManager-0.6.6
 ==============================================
diff --git a/TODO b/TODO
index 369be1e5..3b8438ac 100644
--- a/TODO
+++ b/TODO
@@ -495,3 +495,123 @@ a bridge or bond and shouldn't be automatically started by NetworkManager or
 displayed as separate connections in the user interface.
 
 TO BE CONTINUED
+
+
+* Better Tablet/Mobile Behavior
+
+There are a few components to this:
+
+1) kernel driver and hardware capabilities: most mobile devices use periodic
+background scanning to quickly determine whether a known SSID is available and
+notify the connection manager to connect to it.  This typically requires special
+capabilities and good powersave/sleep support from the WiFi kernel driver.
+There is a background scanning API in nl80211, but we need to determine how many
+SSIDs each driver allows for background scanning, and based on that number, give
+the driver the most recent N SSIDs.  We still need to periodically wake the
+device up and do a full scan just in case the user is near a known SSID that was
+not in the N top recently used networks.  This is also beneficial to normal
+desktop use-cases.
+
+wpa_supplicant doesn't currently provide an explicit interface for sending SSIDs
+to the driver for background scanning, but could simply send a list using
+configured networks.  However, NM currently does not send *all* configured
+connections' SSIDs to the supplicant, so that's something we should do first
+to optimize connection times.  To do this, NM would need to order all networks
+using the NM timestamp and convert that into a supplicant priority number, which
+would need to be adjusted periodically when the timestamp was updated.  This
+would involve tracking each network (exposed by the supplicant as a D-Bus
+object) and making sure they were added, deleted, and updated when the backing
+NMConnection objects changed.  One complication is that the supplicant
+requires secrets for various network types when the network is added via D-Bus,
+and NetworkManager might not have those secrets yet.  We may need to modify
+the supplicant allow for *all* secrets (PSKs, WEP keys, etc) to be requested
+on-demand, not just EAP secrets like 802.1x passwords.  We then need to fix
+up the supplicant's D-Bus interface to actually send requests for secrets out
+over D-Bus (like wpa_supplicant_eap_param_needed() does for the socket-based
+control interface) and to handle the resulting reply from a D-Bus client like
+wpa_supplicant_ctrl_iface_ctrl_rsp() does.
+
+With the secrets request stuff and priority handling in place, wpa_supplicant
+would control network selection and roaming (based on the priorities NM gave it
+of course) instead of NetworkManager itself, and hopefully lead to a faster WiFi
+connection process.
+
+2) single-device-at-a-time with overlapping connections: this is also probably
+the best route to go for desktop use-cases as well.  Instead of bringing all
+available connections up, only bring up the "best" connection at any given
+time based on the current priority list (which is rougly Ethernet > WiFi >
+3G/Bluetooth/WiMAX).  However, to ensure seamless connectivity, when one
+connection begins to degrade, the next-best connection should be started before
+the current one is terminated, such that there is a small amount of overlap.
+Consequently the same behavior should be used when a better connection becomes
+available.  This behavior should be suspended when special connections like
+Internet Connection Sharing ones are started, where clearly the priorities
+are different (ie, for Mobile Hotspot 3G > WiFi).
+
+
+* IP over Infiniband (IPoIB)
+
+These interfaces are similar to Ethernet interfaces with a few distinct
+differences:
+
+  1) they have 64-bit MAC addresses (GUIDs in Infiniband parlance)
+  2) DHCP clients need to be modified to handle IPoIB
+  3) they have a different ARP type and different L2 options
+
+By default the interfaces do not have IP capability, but they gain that
+capability when certain kernel modules (ib_ipoib.ko) are loaded, which causes
+the IP-capable interface is created.  The IP-capable interfaces apparently have
+ARPHRD_INFINIBAND set, which is likely what NM should use to identify them.
+
+One outstanding question is whether NM should (a) detect all Infiniband
+interfaces and load ib_ipoib.ko only when there is a defined NMConnection for
+an Infiniband interface, or (b) whether NM should automatically load ib_ipoib.ko
+for every Infiniband interface, or (c) whether NM should only manage Infiniband
+interfaces that already have associated IP-capable interfaces (ie, something
+else is responsible for loading ib_ipoib.ko).  Depending on our implementation,
+(a) might not be possible, because if IPoIB connections are treated similar to
+plain Ethernet connections, we may not have any information about whether a
+specific NMConnection is Infiniband other than the MAC address.
+
+It turns out that on some distros other components (like system services) may
+load ib_ipoib.ko for us.  For exmaple, the 'rdma' package on Fedora/RHEL systems
+contains /etc/rc.d/init.d/rdma which uses values in /etc/rdma/rdma.conf to load
+ib_ipoib.ko at system startup if the user has requested it via IPOIB_LOAD=yes.
+For the time being, if the some other component of the system loads IP for us,
+NetworkManager should probably still recognize the Infiniband interface, but
+leave it in unmanaged mode if there is no available IPoIB interface associated
+with the Infiniband one.  i.e. for now, NM should not automatically load
+ib_ipoib.ko.
+
+The second question is whether to fold IPoIB support into the NMDeviceEthernet
+class as was done for s390 network interfaces, or whether to create a subclass
+of NMDevice:
+
+1) extend NMDeviceEthernet: this would involve loosening the assumption that
+hardware addresses (the 'hw-address'/'perm-hw-address' properties of
+NMDeviceEthernet and the 'mac-address'/'cloned-mac-address' properties of
+NMSettingWired) are 48 bits wide and instead can be either 48 or 64 bits wide.
+
+2) create a new NMDevice subclass for Infiniband devices tailored to Infiniband
+specific behavior and attributes.  This would be a lot more code since we'd have
+to duplicate much of what NMDeviceEthernet already does, plus add the
+Infiniband device class to libnm-glib.  This also would be the least invasive
+from an API standpoint since the existing API would be unchanged, except for
+the addition of a new value in the NMDeviceType enum, which clients should
+ignore if they don't understand it.  (Need to coordinate additions to this enum
+between 0.8.x and 0.9.x since 0.9.x has more device types, but we want to make
+sure new device types get the same number for both branches).
+
+For Infiniband specific options we could either fold them into NMSettingEthernet
+or create a new NMSettingInfiniband class.  Current Infiniband specific options
+are partitions/P_Keys, datagram vs. connected mode, and MTU.  The default MTU
+varies with the 'mode'; for datagram it is currently 2044, while for connected
+mode it is currently 65520.  Given that we only have 2 IB-specific options
+we should probably just fold them into NMSettingEthernet similar to what was
+done for s390-specific options.
+
+For some general (and also Red Hat/Fedora specific) information see:
+
+http://tools.ietf.org/html/rfc4392
+http://rhkernel.org/#RHEL6+2.6.32-71.18.2.el6/Documentation/infiniband/ipoib.txt
+
diff --git a/callouts/Makefile.in b/callouts/Makefile.in
index 763d7fb2..191acc8f 100644
--- a/callouts/Makefile.in
+++ b/callouts/Makefile.in
@@ -279,6 +279,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/callouts/tests/Makefile.in b/callouts/tests/Makefile.in
index 4c8fa909..ee28bab1 100644
--- a/callouts/tests/Makefile.in
+++ b/callouts/tests/Makefile.in
@@ -188,6 +188,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/cli/Makefile.in b/cli/Makefile.in
index bd3d8737..35852bdc 100644
--- a/cli/Makefile.in
+++ b/cli/Makefile.in
@@ -192,6 +192,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/cli/src/Makefile.in b/cli/src/Makefile.in
index 33aa3f2b..83917947 100644
--- a/cli/src/Makefile.in
+++ b/cli/src/Makefile.in
@@ -189,6 +189,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/cli/src/connections.c b/cli/src/connections.c
index 5febc58a..f45d95a5 100644
--- a/cli/src/connections.c
+++ b/cli/src/connections.c
@@ -141,39 +141,26 @@ typedef struct {
 	char **argv;
 } ArgsInfo;
 
-extern GMainLoop *loop;   /* glib main loop variable */
+/* glib main loop variable - defined in nmcli.c */
+extern GMainLoop *loop;
 
 static ArgsInfo args_info;
 
-/* static function prototypes */
-static void usage (void);
-static void quit (void);
-static void show_connection (NMConnection *data, gpointer user_data);
-static NMConnection *find_connection (GSList *list, const char *filter_type, const char *filter_val);
-static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
-                                            const char *nsp, NMDevice **device, const char **spec_object, GError **error);
-static const char *active_connection_state_to_string (NMActiveConnectionState state);
-static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data);
-static void get_connections_cb (NMRemoteSettings *settings, gpointer user_data);
-static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connection_down (NmCli *nmc, int argc, char **argv);
-
 static void
 usage (void)
 {
 	fprintf (stderr,
 	         _("Usage: nmcli con { COMMAND | help }\n"
-	         "  COMMAND := { list | status | up | down }\n\n"
+	         "  COMMAND := { list | status | up | down | delete }\n\n"
 	         "  list [id <id> | uuid <id>]\n"
 	         "  status\n"
 #if WITH_WIMAX
-	         "  up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [nsp <name>] [--nowait] [--timeout <timeout>]\n"
+	         "  up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [nsp <name>] [--nowait] [--timeout <timeout>]\n"
 #else
-	         "  up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
+	         "  up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [--nowait] [--timeout <timeout>]\n"
 #endif
-	         "  down id <id> | uuid <id>\n"));
+	         "  down id <id> | uuid <id>\n"
+	         "  delete id <id> | uuid <id>\n"));
 }
 
 /* The real commands that do something - i.e. not 'help', etc. */
@@ -182,6 +169,7 @@ static const char *real_con_commands[] = {
 	"status",
 	"up",
 	"down",
+	"delete",
 	NULL
 };
 
@@ -1073,7 +1061,7 @@ find_device_for_connection (NmCli *nmc,
 	g_assert (s_con);
 	con_type = nm_setting_connection_get_connection_type (s_con);
 
-	if (strcmp (con_type, "vpn") == 0) {
+	if (strcmp (con_type, NM_SETTING_VPN_SETTING_NAME) == 0) {
 		/* VPN connections */
 		NMActiveConnection *active = NULL;
 		if (iface) {
@@ -1116,22 +1104,22 @@ find_device_for_connection (NmCli *nmc,
 				}
 			}
 
-			if (found_device && ap && !strcmp (con_type, "802-11-wireless") && NM_IS_DEVICE_WIFI (dev)) {
-				char *hwaddr_up = g_ascii_strup (ap, -1);
+			if (found_device && ap && !strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME) && NM_IS_DEVICE_WIFI (dev)) {
+				char *bssid_up = g_ascii_strup (ap, -1);
 				const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
 				found_device = NULL;  /* Mark as not found; set to the device again later, only if AP matches */
 
 				for (j = 0; aps && (j < aps->len); j++) {
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+					if (!strcmp (bssid_up, candidate_bssid)) {
 						found_device = dev;
 						*spec_object = nm_object_get_path (NM_OBJECT (candidate_ap));
 						break;
 					}
 				}
-				g_free (hwaddr_up);
+				g_free (bssid_up);
 			}
 
 #if WITH_WIMAX
@@ -1576,6 +1564,66 @@ error:
 }
 
 static NMCResultCode
+do_connection_delete (NmCli *nmc, int argc, char **argv)
+{
+	NMConnection *connection = NULL;
+	const char *selector;
+	const char *id = NULL;
+	GError *error = NULL;
+
+	nmc->should_wait = FALSE;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
+			selector = *argv;
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+			id = *argv;
+		}
+		else
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+
+		argc--;
+		argv++;
+	}
+
+	if (!id) {
+		g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	if (!nmc_is_nm_running (nmc, &error)) {
+		if (error) {
+			g_string_printf (nmc->return_text, _("Error: Can't find out if NetworkManager is running: %s."), error->message);
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			g_error_free (error);
+		} else {
+			g_string_printf (nmc->return_text, _("Error: NetworkManager is not running."));
+			nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING;
+		}
+		goto error;
+	}
+
+	connection = find_connection (nmc->system_connections, selector, id);
+
+	if (!connection) {
+		g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), id);
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		goto error;
+	}
+
+	/* Delete the connection */
+	nm_remote_connection_delete (NM_REMOTE_CONNECTION (connection), NULL, NULL);
+
+error:
+	return nmc->return_value;
+}
+
+static NMCResultCode
 parse_cmd (NmCli *nmc, int argc, char **argv)
 {
 	GError *error = NULL;
@@ -1600,6 +1648,9 @@ parse_cmd (NmCli *nmc, int argc, char **argv)
 		else if (matches(*argv, "down") == 0) {
 			nmc->return_value = do_connection_down (nmc, argc-1, argv+1);
 		}
+		else if (matches(*argv, "delete") == 0) {
+			nmc->return_value = do_connection_delete (nmc, argc-1, argv+1);
+		}
 		else if (matches (*argv, "help") == 0) {
 			usage ();
 			nmc->should_wait = FALSE;
@@ -1672,6 +1723,7 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (error || !bus) {
 			g_string_printf (nmc->return_text, _("Error: could not connect to D-Bus."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
 		}
 
@@ -1679,8 +1731,8 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (!(nmc->system_settings = nm_remote_settings_new (bus))) {
 			g_string_printf (nmc->return_text, _("Error: Could not get system settings."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
-
 		}
 
 		/* find out whether settings service is running */
@@ -1689,6 +1741,7 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (!nmc->system_settings_running) {
 			g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings service is not running."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
 		}
 
diff --git a/cli/src/devices.c b/cli/src/devices.c
index c6228ba1..500d2341 100644
--- a/cli/src/devices.c
+++ b/cli/src/devices.c
@@ -236,18 +236,8 @@ static NmcOutputField nmc_fields_dev_wimax_list[] = {
 #endif
 
 
-/* static function prototypes */
-static void usage (void);
-static const char *device_state_to_string (NMDeviceState state);
-static NMCResultCode do_devices_status (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_devices_list (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_device_disconnect (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv);
-#if WITH_WIMAX
-static NMCResultCode do_device_wimax (NmCli *nmc, int argc, char **argv);
-#endif
-
-extern GMainLoop *loop;   /* glib main loop variable */
+/* glib main loop variable - defined in nmcli.c */
+extern GMainLoop *loop;
 
 static void
 usage (void)
@@ -262,7 +252,7 @@ usage (void)
 	         "  status\n"
 	         "  list [iface <iface>]\n"
 	         "  disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
-	         "  wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n"
+	         "  wifi [list [iface <iface>] [bssid <BSSID>]]\n"
 #if WITH_WIMAX
 	         "  wimax [list [iface <iface>] [nsp <name>]]\n\n"
 #endif
@@ -441,15 +431,15 @@ detail_access_point (gpointer data, gpointer user_data)
 	NM80211ApSecurityFlags wpa_flags, rsn_flags;
 	guint32 freq, bitrate;
 	guint8 strength;
-	const GByteArray *ssid; 
-	const char *hwaddr;
+	const GByteArray *ssid;
+	const char *bssid;
 	NM80211Mode mode;
 	char *freq_str, *ssid_str, *bitrate_str, *strength_str, *wpa_flags_str, *rsn_flags_str;
 	GString *security_str;
 	char *ap_name;
 
 	if (info->active_bssid) {
-		const char *current_bssid = nm_access_point_get_hw_address (ap);
+		const char *current_bssid = nm_access_point_get_bssid (ap);
 		if (current_bssid && !strcmp (current_bssid, info->active_bssid))
 			active = TRUE;
 	}
@@ -459,7 +449,7 @@ detail_access_point (gpointer data, gpointer user_data)
 	wpa_flags = nm_access_point_get_wpa_flags (ap);
 	rsn_flags = nm_access_point_get_rsn_flags (ap);
 	ssid = nm_access_point_get_ssid (ap);
-	hwaddr = nm_access_point_get_hw_address (ap);
+	bssid = nm_access_point_get_bssid (ap);
 	freq = nm_access_point_get_frequency (ap);
 	mode = nm_access_point_get_mode (ap);
 	bitrate = nm_access_point_get_max_bitrate (ap);
@@ -497,7 +487,7 @@ detail_access_point (gpointer data, gpointer user_data)
 	ap_name = g_strdup_printf ("AP%d", info->index++); /* AP */
 	info->nmc->allowed_fields[0].value = ap_name;
 	info->nmc->allowed_fields[1].value = ssid_str;
-	info->nmc->allowed_fields[2].value = hwaddr;
+	info->nmc->allowed_fields[2].value = bssid;
 	info->nmc->allowed_fields[3].value = mode == NM_802_11_MODE_ADHOC ? _("Ad-Hoc") : mode == NM_802_11_MODE_INFRA ? _("Infrastructure") : _("Unknown");
 	info->nmc->allowed_fields[4].value = freq_str;
 	info->nmc->allowed_fields[5].value = bitrate_str;
@@ -725,7 +715,7 @@ show_device_info (gpointer data, gpointer user_data)
 			if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[3].name)) {
 				if (state == NM_DEVICE_STATE_ACTIVATED) {
 					active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
-					active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+					active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL;
 				}
 
 				nmc->allowed_fields = nmc_fields_dev_wifi_list;
@@ -1275,7 +1265,7 @@ show_acces_point_info (NMDevice *device, NmCli *nmc)
 
 	if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
 		active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
-		active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+		active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL;
 	}
 
 	info = g_malloc0 (sizeof (APInfo));
@@ -1296,7 +1286,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 	NMDevice *device = NULL;
 	NMAccessPoint *ap = NULL;
 	const char *iface = NULL;
-	const char *hwaddr_user = NULL;
+	const char *bssid_user = NULL;
 	const GPtrArray *devices;
 	const GPtrArray *aps;
 	APInfo *info;
@@ -1316,13 +1306,14 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 				goto error;
 			}
 			iface = *argv;
-		} else if (strcmp (*argv, "hwaddr") == 0) {
+		} else if (strcmp (*argv, "bssid") == 0 || strcmp (*argv, "hwaddr") == 0) {
+			/* hwaddr is deprecated and will be removed later */
 			if (next_arg (&argc, &argv) != 0) {
 				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
 				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
 				goto error;
 			}
-			hwaddr_user = *argv;
+			bssid_user = *argv;
 		} else {
 			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
 		}
@@ -1392,21 +1383,21 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 		}
 
 		if (NM_IS_DEVICE_WIFI (device)) {
-			if (hwaddr_user) {
+			if (bssid_user) {
 				/* Specific AP requested - list only that */
 				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
 				for (j = 0; aps && (j < aps->len); j++) {
-					char *hwaddr_up;
+					char *bssid_up;
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
-					if (!strcmp (hwaddr_up, candidate_hwaddr))
+					bssid_up = g_ascii_strup (bssid_user, -1);
+					if (!strcmp (bssid_up, candidate_bssid))
 						ap = candidate_ap;
-					g_free (hwaddr_up);
+					g_free (bssid_up);
 				}
 				if (!ap) {
-				 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+				 	g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user);
 					nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 					goto error;
 				}
@@ -1430,7 +1421,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 	} else {
 		/* List APs for all devices */
 		print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-		if (hwaddr_user) {
+		if (bssid_user) {
 			/* Specific AP requested - list only that */
 			for (i = 0; devices && (i < devices->len); i++) {
 				NMDevice *dev = g_ptr_array_index (devices, i);
@@ -1440,12 +1431,12 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 
 				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
 				for (j = 0; aps && (j < aps->len); j++) {
-					char *hwaddr_up;
+					char *bssid_up;
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
-					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+					bssid_up = g_ascii_strup (bssid_user, -1);
+					if (!strcmp (bssid_up, candidate_bssid)) {
 						ap = candidate_ap;
 
 						info = g_malloc0 (sizeof (APInfo));
@@ -1456,11 +1447,11 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 						detail_access_point (ap, info);
 						g_free (info);
 					}
-					g_free (hwaddr_up);
+					g_free (bssid_up);
 				}
 			}
 			if (!ap) {
-			 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+			 	g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user);
 				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 				goto error;
 			}
@@ -1667,7 +1658,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv)
 				}
 			}
 			if (!nsp) {
-			 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), nsp_user);
+			 	g_string_printf (nmc->return_text, _("Error: Access point with nsp '%s' not found."), nsp_user);
 				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 				goto error;
 			}
diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c
index ac9a3841..c23c9fae 100644
--- a/cli/src/network-manager.c
+++ b/cli/src/network-manager.c
@@ -57,16 +57,9 @@ static NmcOutputField nmc_fields_nm_status[] = {
 #define NMC_FIELDS_NM_WWAN           "WWAN"
 #define NMC_FIELDS_NM_WIMAX          "WIMAX"
 
-
+/* glib main loop variable - defined in nmcli.c */
 extern GMainLoop *loop;
 
-/* static function prototypes */
-static void usage (void);
-static void quit (void);
-static const char *nm_state_to_string (NMState state);
-static NMCResultCode show_nm_status (NmCli *nmc);
-
-
 static void
 usage (void)
 {
diff --git a/cli/src/settings.c b/cli/src/settings.c
index c2385370..ccbe9589 100644
--- a/cli/src/settings.c
+++ b/cli/src/settings.c
@@ -14,7 +14,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2010 Red Hat, Inc.
+ * (C) Copyright 2010 - 2011 Red Hat, Inc.
  */
 
 #include "config.h"
@@ -39,6 +39,7 @@ static NmcOutputField nmc_fields_setting_connection[] = {
 	SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT, 13),  /* 4 */
 	SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP, 10),    /* 5 */
 	SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY, 10),    /* 6 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS, 30),  /* 7 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_CONNECTION_ALL     "name"","\
@@ -47,19 +48,24 @@ static NmcOutputField nmc_fields_setting_connection[] = {
                                               NM_SETTING_CONNECTION_TYPE","\
                                               NM_SETTING_CONNECTION_AUTOCONNECT","\
                                               NM_SETTING_CONNECTION_TIMESTAMP","\
-                                              NM_SETTING_CONNECTION_READ_ONLY
+                                              NM_SETTING_CONNECTION_READ_ONLY","\
+                                              NM_SETTING_CONNECTION_PERMISSIONS
 #define NMC_FIELDS_SETTING_CONNECTION_COMMON  NMC_FIELDS_SETTING_CONNECTION_ALL
 
 /* Available fields for NM_SETTING_WIRED_SETTING_NAME */
 static NmcOutputField nmc_fields_setting_wired[] = {
-	SETTING_FIELD ("name",  17),                             /* 0 */
-	SETTING_FIELD (NM_SETTING_WIRED_PORT, 8),                /* 1 */
-	SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10),              /* 2 */
-	SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10),             /* 3 */
-	SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15),     /* 4 */
-	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19),        /* 5 */
-	SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, 19), /* 6 */
-	SETTING_FIELD (NM_SETTING_WIRED_MTU, 6),                 /* 7 */
+	SETTING_FIELD ("name",  17),                                  /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRED_PORT, 8),                     /* 1 */
+	SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10),                   /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10),                  /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15),          /* 4 */
+	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19),             /* 5 */
+	SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, 19),      /* 6 */
+	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, 39),   /* 7 */
+	SETTING_FIELD (NM_SETTING_WIRED_MTU, 6),                      /* 8 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS, 20),        /* 9 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE, 15),            /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS, 20),            /* 11 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_WIRED_ALL     "name"","\
@@ -69,7 +75,11 @@ static NmcOutputField nmc_fields_setting_wired[] = {
                                          NM_SETTING_WIRED_AUTO_NEGOTIATE","\
                                          NM_SETTING_WIRED_MAC_ADDRESS","\
                                          NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
-                                         NM_SETTING_WIRED_MTU
+                                         NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST","\
+                                         NM_SETTING_WIRED_MTU","\
+                                         NM_SETTING_WIRED_S390_SUBCHANNELS","\
+                                         NM_SETTING_WIRED_S390_NETTYPE","\
+                                         NM_SETTING_WIRED_S390_OPTIONS
 #define NMC_FIELDS_SETTING_WIRED_COMMON  NMC_FIELDS_SETTING_WIRED_ALL
 
 /* Available fields for NM_SETTING_802_1X_SETTING_NAME */
@@ -80,22 +90,26 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
 	SETTING_FIELD (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, 15),           /* 3 */
 	SETTING_FIELD (NM_SETTING_802_1X_CA_CERT, 10),                      /* 4 */
 	SETTING_FIELD (NM_SETTING_802_1X_CA_PATH, 10),                      /* 5 */
-	SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT, 10),                  /* 6 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER, 10),               /* 7 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL, 10),             /* 8 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, 10),     /* 9 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH, 10),                  /* 10 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP, 10),               /* 11 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT, 20),               /* 12 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH, 20),               /* 13 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, 20),           /* 14 */
-	SETTING_FIELD (NM_SETTING_802_1X_PASSWORD, 10),                     /* 15 */
-	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY, 15),                  /* 16 */
-	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, 20),         /* 17 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20),           /* 18 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20),  /* 19 */
-	SETTING_FIELD (NM_SETTING_802_1X_PIN, 8),                           /* 20 */
-	SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17),              /* 21 */
+	SETTING_FIELD (NM_SETTING_802_1X_SUBJECT_MATCH, 10),                /* 6 */
+	SETTING_FIELD (NM_SETTING_802_1X_ALTSUBJECT_MATCHES, 10),           /* 7 */
+	SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT, 10),                  /* 8 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER, 10),               /* 9 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL, 10),             /* 10 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, 10),     /* 11 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH, 10),                  /* 12 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP, 10),               /* 13 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT, 20),               /* 14 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH, 20),               /* 15 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, 10),         /* 16 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, 10),    /* 17 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, 20),           /* 18 */
+	SETTING_FIELD (NM_SETTING_802_1X_PASSWORD, 10),                     /* 19 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY, 15),                  /* 20 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, 20),         /* 21 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20),           /* 22 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20),  /* 23 */
+	SETTING_FIELD (NM_SETTING_802_1X_PIN, 8),                           /* 24 */
+	SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17),              /* 25 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_802_1X_ALL     "name"","\
@@ -104,6 +118,8 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
                                           NM_SETTING_802_1X_ANONYMOUS_IDENTITY","\
                                           NM_SETTING_802_1X_CA_CERT","\
                                           NM_SETTING_802_1X_CA_PATH","\
+                                          NM_SETTING_802_1X_SUBJECT_MATCH","\
+                                          NM_SETTING_802_1X_ALTSUBJECT_MATCHES","\
                                           NM_SETTING_802_1X_CLIENT_CERT","\
                                           NM_SETTING_802_1X_PHASE1_PEAPVER","\
                                           NM_SETTING_802_1X_PHASE1_PEAPLABEL","\
@@ -112,6 +128,8 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
                                           NM_SETTING_802_1X_PHASE2_AUTHEAP","\
                                           NM_SETTING_802_1X_PHASE2_CA_CERT","\
                                           NM_SETTING_802_1X_PHASE2_CA_PATH","\
+                                          NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH","\
+                                          NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES","\
                                           NM_SETTING_802_1X_PHASE2_CLIENT_CERT","\
                                           NM_SETTING_802_1X_PASSWORD","\
                                           NM_SETTING_802_1X_PRIVATE_KEY","\
@@ -134,9 +152,10 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
 	SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER, 10),                  /* 7 */
 	SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS, 19),               /* 8 */
 	SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, 19),        /* 9 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6),                        /* 10 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35),               /* 11 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10),                       /* 12 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, 39),     /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6),                        /* 11 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35),               /* 12 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10),                       /* 13 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_WIRELESS_ALL     "name"","\
@@ -149,6 +168,7 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
                                             NM_SETTING_WIRELESS_TX_POWER","\
                                             NM_SETTING_WIRELESS_MAC_ADDRESS","\
                                             NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS","\
+                                            NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST","\
                                             NM_SETTING_WIRELESS_MTU","\
                                             NM_SETTING_WIRELESS_SEEN_BSSIDS","\
                                             NM_SETTING_WIRELESS_SEC
@@ -204,6 +224,7 @@ static NmcOutputField nmc_fields_setting_ip4_config[] = {
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, 19),      /* 9 */
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, 14),           /* 10 */
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, 15),           /* 11 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_MAY_FAIL, 12),                /* 12 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_IP4_CONFIG_ALL     "name"","\
@@ -217,7 +238,8 @@ static NmcOutputField nmc_fields_setting_ip4_config[] = {
                                               NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID","\
                                               NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME","\
                                               NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME","\
-                                              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT
+                                              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT","\
+                                              NM_SETTING_IP4_CONFIG_MAY_FAIL
 #define NMC_FIELDS_SETTING_IP4_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
 
 /* Available fields for NM_SETTING_IP6_CONFIG_SETTING_NAME */
@@ -231,6 +253,7 @@ static NmcOutputField nmc_fields_setting_ip6_config[] = {
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, 19),      /* 6 */
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, 16),         /* 7 */
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, 15),           /* 8 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_MAY_FAIL, 12),                /* 9 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_IP6_CONFIG_ALL     "name"","\
@@ -241,7 +264,8 @@ static NmcOutputField nmc_fields_setting_ip6_config[] = {
                                               NM_SETTING_IP6_CONFIG_ROUTES","\
                                               NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES","\
                                               NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS","\
-                                              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT
+                                              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT","\
+                                              NM_SETTING_IP6_CONFIG_MAY_FAIL
 #define NMC_FIELDS_SETTING_IP6_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
 
 /* Available fields for NM_SETTING_SERIAL_SETTING_NAME */
@@ -480,6 +504,10 @@ allowed_bands_to_string (guint32 bands)
 		g_string_append (band_str, _("WCDMA 3GPP UMTS 900 MHz, "));
 	if (bands & NM_SETTING_GSM_BAND_U17IX)
 		g_string_append (band_str, _("WCDMA 3GPP UMTS 1700 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U1900)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 1900 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U2600)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 2600 MHz, "));
 
 	if (band_str->str[band_str->len-1] == '(')
 		g_string_assign (band_str, _("unknown"));
@@ -491,13 +519,16 @@ allowed_bands_to_string (guint32 bands)
 	return g_string_free (band_str, FALSE);
 }
 
-
 gboolean
 setting_connection_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSettingConnection *s_con;
 	guint64 timestamp;
 	char *timestamp_str;
+	const char *perm_item;
+	const char *perm_type;
+	GString *perm = NULL;
+	int i;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -513,6 +544,15 @@ setting_connection_details (NMSetting *setting, NmCli *nmc)
 	timestamp = nm_setting_connection_get_timestamp (s_con);
 	timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
 
+	/* get permissions */
+	perm = g_string_new (NULL);
+	for (i = 0; i < nm_setting_connection_get_num_permissions (s_con); i++) {
+		nm_setting_connection_get_permission (s_con, i, &perm_type, &perm_item, NULL);
+		g_string_append_printf (perm, "%s:%s,", perm_type, perm_item);
+	}
+	if (perm->len > 0)
+		g_string_truncate (perm, perm->len-1); /* remove trailing , */
+
 	nmc->allowed_fields[0].value = NM_SETTING_CONNECTION_SETTING_NAME;
 	nmc->allowed_fields[1].value = nm_setting_connection_get_id (s_con);
 	nmc->allowed_fields[2].value = nm_setting_connection_get_uuid (s_con);
@@ -520,11 +560,13 @@ setting_connection_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[4].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no");
 	nmc->allowed_fields[5].value = timestamp_str;
 	nmc->allowed_fields[6].value = nm_setting_connection_get_read_only (s_con) ? ("yes") : _("no");
+	nmc->allowed_fields[7].value = perm->str;
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
 
 	g_free (timestamp_str);
+	g_string_free (perm, TRUE);
 
 	return TRUE;
 }
@@ -534,7 +576,11 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSettingWired *s_wired;
 	const GByteArray *mac;
+	const GSList *iter;
+	const GPtrArray *s390_channels;
+	int i;
 	char *speed_str, *mtu_str, *device_mac_str = NULL, *cloned_mac_str = NULL;
+	GString *mac_blacklist_s, *s390_channels_s, *s390_options_s;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -556,6 +602,29 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	if (mac)
 		cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
 
+	mac_blacklist_s = g_string_new (NULL);
+	iter = nm_setting_wired_get_mac_address_blacklist (s_wired);
+	while (iter) {
+		g_string_append_printf (mac_blacklist_s, "%s,", (char *) iter->data);
+		iter = iter->next;
+	}
+	g_string_truncate (mac_blacklist_s, mac_blacklist_s->len-1);  /* chop off trailing ',' */
+
+	s390_channels_s = g_string_new (NULL);
+	s390_channels = nm_setting_wired_get_s390_subchannels (s_wired);
+	for (i = 0; s390_channels && i < s390_channels->len; i++)
+		g_string_append_printf (s390_channels_s, "%s,", (char *) g_ptr_array_index (s390_channels, i));
+	g_string_truncate (s390_channels_s, s390_channels_s->len-1);  /* chop off trailing ',' */
+
+	s390_options_s = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wired_get_num_s390_options (s_wired); i++) {
+		const char *key, *value;
+
+		nm_setting_wired_get_s390_option (s_wired, i, &key, &value);
+		g_string_append_printf (s390_options_s, "%s=%s,", key, value);
+	}
+	g_string_truncate (s390_options_s, s390_options_s->len-1);  /* chop off trailing ',' */
+
 	nmc->allowed_fields[0].value = NM_SETTING_WIRED_SETTING_NAME;
 	nmc->allowed_fields[1].value = nm_setting_wired_get_port (s_wired);
 	nmc->allowed_fields[2].value = speed_str;
@@ -563,7 +632,11 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[4].value = nm_setting_wired_get_auto_negotiate (s_wired) ? _("yes") : _("no");
 	nmc->allowed_fields[5].value = device_mac_str;
 	nmc->allowed_fields[6].value = cloned_mac_str;
-	nmc->allowed_fields[7].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
+	nmc->allowed_fields[7].value = mac_blacklist_s->str;
+	nmc->allowed_fields[8].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
+	nmc->allowed_fields[9].value = s390_channels_s->str;
+	nmc->allowed_fields[10].value = nm_setting_wired_get_s390_nettype (s_wired);
+	nmc->allowed_fields[11].value = s390_options_s->str;
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -572,6 +645,9 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	g_free (device_mac_str);
 	g_free (cloned_mac_str);
 	g_free (mtu_str);
+	g_string_free (mac_blacklist_s, TRUE);
+	g_string_free (s390_channels_s, TRUE);
+	g_string_free (s390_options_s, TRUE);
 
 	return TRUE;
 }
@@ -581,7 +657,7 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSetting8021x *s_8021X;
 	NMSetting8021xCKScheme scheme;
-	GString *eap_str;
+	GString *eap_str, *alt_sub_match, *phase2_alt_sub_match;
 	char *ca_cert_str = NULL, *client_cert_str = NULL, *phase2_ca_cert_str = NULL;
 	char *phase2_client_cert_str = NULL, *private_key_str = NULL, *phase2_private_key_str = NULL;
 	int i;
@@ -639,28 +715,42 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
 		phase2_private_key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X));
 
+	alt_sub_match = g_string_new (NULL);
+	for (i = 0; i < nm_setting_802_1x_get_num_altsubject_matches (s_8021X); i++)
+		g_string_append_printf (alt_sub_match, "%s,", nm_setting_802_1x_get_altsubject_match (s_8021X, i));
+	g_string_truncate (alt_sub_match, alt_sub_match->len-1);  /* chop off trailing ',' */
+
+	phase2_alt_sub_match = g_string_new (NULL);
+	for (i = 0; i < nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021X); i++)
+		g_string_append_printf (phase2_alt_sub_match, "%s,", nm_setting_802_1x_get_phase2_altsubject_match (s_8021X, i));
+	g_string_truncate (phase2_alt_sub_match, phase2_alt_sub_match->len-1);  /* chop off trailing ',' */
+
 	nmc->allowed_fields[0].value = NM_SETTING_802_1X_SETTING_NAME;
 	nmc->allowed_fields[1].value = eap_str->str;
 	nmc->allowed_fields[2].value = nm_setting_802_1x_get_identity (s_8021X);
 	nmc->allowed_fields[3].value = nm_setting_802_1x_get_anonymous_identity (s_8021X);
 	nmc->allowed_fields[4].value = ca_cert_str;
 	nmc->allowed_fields[5].value = nm_setting_802_1x_get_ca_path (s_8021X);
-	nmc->allowed_fields[6].value = client_cert_str;
-	nmc->allowed_fields[7].value = nm_setting_802_1x_get_phase1_peapver (s_8021X);
-	nmc->allowed_fields[8].value = nm_setting_802_1x_get_phase1_peaplabel (s_8021X);
-	nmc->allowed_fields[9].value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021X);
-	nmc->allowed_fields[10].value = nm_setting_802_1x_get_phase2_auth (s_8021X);
-	nmc->allowed_fields[11].value = nm_setting_802_1x_get_phase2_autheap (s_8021X);
-	nmc->allowed_fields[12].value = phase2_ca_cert_str;
-	nmc->allowed_fields[13].value = nm_setting_802_1x_get_phase2_ca_path (s_8021X);
-	nmc->allowed_fields[14].value = phase2_client_cert_str;
-	nmc->allowed_fields[15].value = nm_setting_802_1x_get_password (s_8021X);
-	nmc->allowed_fields[16].value = private_key_str;
-	nmc->allowed_fields[17].value = nm_setting_802_1x_get_private_key_password (s_8021X);
-	nmc->allowed_fields[18].value = phase2_private_key_str;
-	nmc->allowed_fields[19].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X);
-	nmc->allowed_fields[20].value = nm_setting_802_1x_get_pin (s_8021X);
-	nmc->allowed_fields[21].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no");
+	nmc->allowed_fields[6].value = nm_setting_802_1x_get_subject_match (s_8021X);
+	nmc->allowed_fields[7].value = alt_sub_match->str;
+	nmc->allowed_fields[8].value = client_cert_str;
+	nmc->allowed_fields[9].value = nm_setting_802_1x_get_phase1_peapver (s_8021X);
+	nmc->allowed_fields[10].value = nm_setting_802_1x_get_phase1_peaplabel (s_8021X);
+	nmc->allowed_fields[11].value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021X);
+	nmc->allowed_fields[12].value = nm_setting_802_1x_get_phase2_auth (s_8021X);
+	nmc->allowed_fields[13].value = nm_setting_802_1x_get_phase2_autheap (s_8021X);
+	nmc->allowed_fields[14].value = phase2_ca_cert_str;
+	nmc->allowed_fields[15].value = nm_setting_802_1x_get_phase2_ca_path (s_8021X);
+	nmc->allowed_fields[16].value = nm_setting_802_1x_get_phase2_subject_match (s_8021X);
+	nmc->allowed_fields[17].value = phase2_alt_sub_match->str;
+	nmc->allowed_fields[18].value = phase2_client_cert_str;
+	nmc->allowed_fields[19].value = nm_setting_802_1x_get_password (s_8021X);
+	nmc->allowed_fields[20].value = private_key_str;
+	nmc->allowed_fields[21].value = nm_setting_802_1x_get_private_key_password (s_8021X);
+	nmc->allowed_fields[22].value = phase2_private_key_str;
+	nmc->allowed_fields[23].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X);
+	nmc->allowed_fields[24].value = nm_setting_802_1x_get_pin (s_8021X);
+	nmc->allowed_fields[25].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -672,6 +762,8 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 	g_free (private_key_str);
 	g_free (phase2_private_key_str);
 	g_string_free (eap_str, TRUE);
+	g_string_free (alt_sub_match, TRUE);
+	g_string_free (phase2_alt_sub_match, TRUE);
 
 	return TRUE;
 }
@@ -684,7 +776,8 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	const GByteArray *ssid, *bssid, *mac;
 	char *ssid_str, *channel_str, *rate_str, *tx_power_str, *mtu_str;
 	char *device_mac_str = NULL, *cloned_mac_str = NULL, *bssid_str = NULL;
-	GString *seen_bssids;
+	GString *mac_blacklist, *seen_bssids;
+	const GSList *iter;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -712,6 +805,15 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
 	if (mac)
 		cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
+
+	mac_blacklist = g_string_new (NULL);
+	iter = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
+	while (iter) {
+		g_string_append_printf (mac_blacklist, "%s,", (char *) iter->data);
+		iter = iter->next;
+	}
+	g_string_truncate (mac_blacklist, mac_blacklist->len-1);  /* chop off trailing ',' */
+
 	seen_bssids = g_string_new (NULL);
 	for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (s_wireless); i++) {
 		if (i > 0)
@@ -729,9 +831,10 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[7].value = tx_power_str;
 	nmc->allowed_fields[8].value = device_mac_str ? device_mac_str : _("not set");
 	nmc->allowed_fields[9].value = cloned_mac_str ? cloned_mac_str : _("not set");
-	nmc->allowed_fields[10].value = strcmp (mtu_str, "0") ?  mtu_str : _("auto");
-	nmc->allowed_fields[11].value = seen_bssids->str;
-	nmc->allowed_fields[12].value = nm_setting_wireless_get_security (s_wireless);
+	nmc->allowed_fields[10].value = mac_blacklist->str;
+	nmc->allowed_fields[11].value = strcmp (mtu_str, "0") ?  mtu_str : _("auto");
+	nmc->allowed_fields[12].value = seen_bssids->str;
+	nmc->allowed_fields[13].value = nm_setting_wireless_get_security (s_wireless);
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -745,6 +848,7 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	g_free (cloned_mac_str);
 	g_free (mtu_str);
 	g_string_free (seen_bssids, TRUE);
+	g_string_free (mac_blacklist, TRUE);
 
 	return TRUE;
 }
@@ -940,6 +1044,7 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[9].value = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) ? _("yes") : _("no");
 	nmc->allowed_fields[10].value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
 	nmc->allowed_fields[11].value = nm_setting_ip4_config_get_never_default (s_ip4) ? _("yes") : _("no");
+	nmc->allowed_fields[12].value = nm_setting_ip4_config_get_may_fail (s_ip4) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -1019,6 +1124,11 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc)
 		g_string_append (addr_str, tmp);
 		g_free (tmp);
 
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip6_address_get_gateway (addr);
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		g_string_append_printf (addr_str, ", gw = %s", buf);
+
 		g_string_append (addr_str, " }");
 	}
 
@@ -1067,6 +1177,7 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[6].value = nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? _("yes") : _("no");
 	nmc->allowed_fields[7].value = nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? _("yes") : _("no");
 	nmc->allowed_fields[8].value = nm_setting_ip6_config_get_never_default (s_ip6) ? _("yes") : _("no");
+	nmc->allowed_fields[9].value = nm_setting_ip6_config_get_may_fail (s_ip6) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
diff --git a/cli/src/utils.c b/cli/src/utils.c
index 3c4e4f36..c5637e4f 100644
--- a/cli/src/utils.c
+++ b/cli/src/utils.c
@@ -194,6 +194,7 @@ print_fields (const NmcPrintFields fields, const NmcOutputField field_values[])
 	if (multiline) {
 	/* --- Multiline mode --- */
 		enum { ML_HEADER_WIDTH = 79 };
+		enum { ML_VALUE_INDENT = 40 };
 		if (main_header && pretty) {
 			/* Print the main header */
 			int header_width = nmc_string_screen_width (fields.header_name, NULL) + 4;
@@ -218,7 +219,7 @@ print_fields (const NmcPrintFields fields, const NmcOutputField field_values[])
 				tmp = g_strdup_printf ("%s%s%s:", section_prefix ? field_values[0].value : "",
 				                                  section_prefix ? "." : "",
 				                                  _(field_values[idx].name_l10n));
-				printf ("%-*s%s\n", terse ? 0 : 32, tmp, field_values[idx].value ? field_values[idx].value : not_set_str);
+				printf ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT, tmp, field_values[idx].value ? field_values[idx].value : not_set_str);
 				g_free (tmp);
 			}
 			if (pretty) {
diff --git a/config.h.in b/config.h.in
index bdbd783e..1b6f1bde 100644
--- a/config.h.in
+++ b/config.h.in
@@ -44,6 +44,15 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define if you require libnl-1 legacy support */
+#undef HAVE_LIBNL1
+
+/* Define if you require specific libnl-2 support */
+#undef HAVE_LIBNL2
+
+/* Define if you require specific libnl-3 support */
+#undef HAVE_LIBNL3
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
diff --git a/configure b/configure
index 637c085b..8a4ddc0e 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for NetworkManager 0.9.0.
+# Generated by GNU Autoconf 2.68 for NetworkManager 0.9.1.90.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager>.
 #
@@ -571,8 +571,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='NetworkManager'
 PACKAGE_TARNAME='NetworkManager'
-PACKAGE_VERSION='0.9.0'
-PACKAGE_STRING='NetworkManager 0.9.0'
+PACKAGE_VERSION='0.9.1.90'
+PACKAGE_STRING='NetworkManager 0.9.1.90'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager'
 PACKAGE_URL=''
 
@@ -668,6 +668,12 @@ UUID_LIBS
 UUID_CFLAGS
 LIBNL_LIBS
 LIBNL_CFLAGS
+LIBNL3_LIBS
+LIBNL3_CFLAGS
+LIBNL2_LIBS
+LIBNL2_CFLAGS
+LIBNL1_LIBS
+LIBNL1_CFLAGS
 WITH_CONSOLEKIT_FALSE
 WITH_CONSOLEKIT_TRUE
 HAVE_SYSTEMD_FALSE
@@ -969,8 +975,12 @@ GIO_CFLAGS
 GIO_LIBS
 QT_CFLAGS
 QT_LIBS
-LIBNL_CFLAGS
-LIBNL_LIBS
+LIBNL1_CFLAGS
+LIBNL1_LIBS
+LIBNL2_CFLAGS
+LIBNL2_LIBS
+LIBNL3_CFLAGS
+LIBNL3_LIBS
 UUID_CFLAGS
 UUID_LIBS
 IWMX_SDK_CFLAGS
@@ -1523,7 +1533,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures NetworkManager 0.9.0 to adapt to many kinds of systems.
+\`configure' configures NetworkManager 0.9.1.90 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1593,7 +1603,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of NetworkManager 0.9.0:";;
+     short | recursive ) echo "Configuration of NetworkManager 0.9.1.90:";;
    esac
   cat <<\_ACEOF
 
@@ -1703,9 +1713,15 @@ Some influential environment variables:
   GIO_LIBS    linker flags for GIO, overriding pkg-config
   QT_CFLAGS   C compiler flags for QT, overriding pkg-config
   QT_LIBS     linker flags for QT, overriding pkg-config
-  LIBNL_CFLAGS
-              C compiler flags for LIBNL, overriding pkg-config
-  LIBNL_LIBS  linker flags for LIBNL, overriding pkg-config
+  LIBNL1_CFLAGS
+              C compiler flags for LIBNL1, overriding pkg-config
+  LIBNL1_LIBS linker flags for LIBNL1, overriding pkg-config
+  LIBNL2_CFLAGS
+              C compiler flags for LIBNL2, overriding pkg-config
+  LIBNL2_LIBS linker flags for LIBNL2, overriding pkg-config
+  LIBNL3_CFLAGS
+              C compiler flags for LIBNL3, overriding pkg-config
+  LIBNL3_LIBS linker flags for LIBNL3, overriding pkg-config
   UUID_CFLAGS C compiler flags for UUID, overriding pkg-config
   UUID_LIBS   linker flags for UUID, overriding pkg-config
   IWMX_SDK_CFLAGS
@@ -1787,7 +1803,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-NetworkManager configure 0.9.0
+NetworkManager configure 0.9.1.90
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2331,7 +2347,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by NetworkManager $as_me 0.9.0, which was
+It was created by NetworkManager $as_me 0.9.1.90, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3152,7 +3168,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='NetworkManager'
- VERSION='0.9.0'
+ VERSION='0.9.1.90'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16279,8 +16295,8 @@ fi
 
 NM_MAJOR_VERSION=0
 NM_MINOR_VERSION=9
-NM_MICRO_VERSION=0
-NM_VERSION=0.9.0
+NM_MICRO_VERSION=1
+NM_VERSION=0.9.1.90
 
 
 
@@ -20828,13 +20844,14 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+have_libnl="no"
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL" >&5
-$as_echo_n "checking for LIBNL... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL1" >&5
+$as_echo_n "checking for LIBNL1... " >&6; }
 
-if test -n "$LIBNL_CFLAGS"; then
-    pkg_cv_LIBNL_CFLAGS="$LIBNL_CFLAGS"
+if test -n "$LIBNL1_CFLAGS"; then
+    pkg_cv_LIBNL1_CFLAGS="$LIBNL1_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.0-pre8\""; } >&5
@@ -20842,15 +20859,15 @@ if test -n "$LIBNL_CFLAGS"; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBNL_CFLAGS=`$PKG_CONFIG --cflags "libnl-1 >= 1.0-pre8" 2>/dev/null`
+  pkg_cv_LIBNL1_CFLAGS=`$PKG_CONFIG --cflags "libnl-1 >= 1.0-pre8" 2>/dev/null`
 else
   pkg_failed=yes
 fi
  else
     pkg_failed=untried
 fi
-if test -n "$LIBNL_LIBS"; then
-    pkg_cv_LIBNL_LIBS="$LIBNL_LIBS"
+if test -n "$LIBNL1_LIBS"; then
+    pkg_cv_LIBNL1_LIBS="$LIBNL1_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.0-pre8\""; } >&5
@@ -20858,7 +20875,7 @@ if test -n "$LIBNL_LIBS"; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBNL_LIBS=`$PKG_CONFIG --libs "libnl-1 >= 1.0-pre8" 2>/dev/null`
+  pkg_cv_LIBNL1_LIBS=`$PKG_CONFIG --libs "libnl-1 >= 1.0-pre8" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -20878,50 +20895,201 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBNL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libnl-1 >= 1.0-pre8" 2>&1`
+	        LIBNL1_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libnl-1 >= 1.0-pre8" 2>&1`
         else
-	        LIBNL_PKG_ERRORS=`$PKG_CONFIG --print-errors "libnl-1 >= 1.0-pre8" 2>&1`
+	        LIBNL1_PKG_ERRORS=`$PKG_CONFIG --print-errors "libnl-1 >= 1.0-pre8" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$LIBNL_PKG_ERRORS" >&5
+	echo "$LIBNL1_PKG_ERRORS" >&5
 
-	as_fn_error $? "Package requirements (libnl-1 >= 1.0-pre8) were not met:
+	have_libnl1=no
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_libnl1=no
+else
+	LIBNL1_CFLAGS=$pkg_cv_LIBNL1_CFLAGS
+	LIBNL1_LIBS=$pkg_cv_LIBNL1_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_libnl1=yes
+fi
+if (test "${have_libnl1}" = "yes"); then
 
-$LIBNL_PKG_ERRORS
+$as_echo "#define HAVE_LIBNL1 1" >>confdefs.h
 
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
+	LIBNL_CFLAGS="$LIBNL1_CFLAGS"
+	LIBNL_LIBS="$LIBNL1_LIBS"
+	libnl_version="1"
+	have_libnl="yes"
+fi
 
-Alternatively, you may set the environment variables LIBNL_CFLAGS
-and LIBNL_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details." "$LINENO" 5
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL2" >&5
+$as_echo_n "checking for LIBNL2... " >&6; }
+
+if test -n "$LIBNL2_CFLAGS"; then
+    pkg_cv_LIBNL2_CFLAGS="$LIBNL2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnl-2.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNL2_CFLAGS=`$PKG_CONFIG --cflags "libnl-2.0" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBNL2_LIBS"; then
+    pkg_cv_LIBNL2_LIBS="$LIBNL2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnl-2.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNL2_LIBS=`$PKG_CONFIG --libs "libnl-2.0" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBNL2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libnl-2.0" 2>&1`
+        else
+	        LIBNL2_PKG_ERRORS=`$PKG_CONFIG --print-errors "libnl-2.0" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBNL2_PKG_ERRORS" >&5
+
+	have_libnl2=no
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
+	have_libnl2=no
+else
+	LIBNL2_CFLAGS=$pkg_cv_LIBNL2_CFLAGS
+	LIBNL2_LIBS=$pkg_cv_LIBNL2_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	have_libnl2=yes
+fi
+if (test "${have_libnl2}" = "yes"); then
 
-Alternatively, you may set the environment variables LIBNL_CFLAGS
-and LIBNL_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.
+$as_echo "#define HAVE_LIBNL2 1" >>confdefs.h
+
+	LIBNL_CFLAGS="$LIBNL2_CFLAGS"
+	LIBNL_LIBS="$LIBNL2_LIBS"
+	libnl_version="2"
+	have_libnl="yes"
+fi
 
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details" "$LINENO" 5; }
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL3" >&5
+$as_echo_n "checking for LIBNL3... " >&6; }
+
+if test -n "$LIBNL3_CFLAGS"; then
+    pkg_cv_LIBNL3_CFLAGS="$LIBNL3_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-3.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnl-3.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNL3_CFLAGS=`$PKG_CONFIG --cflags "libnl-3.0" 2>/dev/null`
 else
-	LIBNL_CFLAGS=$pkg_cv_LIBNL_CFLAGS
-	LIBNL_LIBS=$pkg_cv_LIBNL_LIBS
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBNL3_LIBS"; then
+    pkg_cv_LIBNL3_LIBS="$LIBNL3_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-3.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libnl-3.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBNL3_LIBS=`$PKG_CONFIG --libs "libnl-3.0" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBNL3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libnl-3.0" 2>&1`
+        else
+	        LIBNL3_PKG_ERRORS=`$PKG_CONFIG --print-errors "libnl-3.0" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBNL3_PKG_ERRORS" >&5
+
+	have_libnl2=no
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	have_libnl2=no
+else
+	LIBNL3_CFLAGS=$pkg_cv_LIBNL3_CFLAGS
+	LIBNL3_LIBS=$pkg_cv_LIBNL3_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+	have_libnl2=yes
+fi
+if (test "${have_libnl2}" = "yes"); then
+
+$as_echo "#define HAVE_LIBNL3 1" >>confdefs.h
+
+	LIBNL_CFLAGS="$LIBNL3_CFLAGS"
+	LIBNL_LIBS="$LIBNL3_LIBS"
+	libnl_version="3"
+	have_libnl="yes"
+fi
 
+if (test "${have_libnl}" = "no"); then
+	as_fn_error $? "libnl development header are required" "$LINENO" 5
 fi
 
 
 
+if (test "${libnl_version}" = "1"); then
+
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnl address caching bug" >&5
 $as_echo_n "checking for libnl address caching bug... " >&6; }
     save_CFLAGS="$CFLAGS"
@@ -21012,6 +21180,7 @@ $as_echo "?" >&6; }
        ;;
 esac
 
+fi
 
 
 pkg_failed=no
@@ -22929,7 +23098,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by NetworkManager $as_me 0.9.0, which was
+This file was extended by NetworkManager $as_me 0.9.1.90, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -22995,7 +23164,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-NetworkManager config.status 0.9.0
+NetworkManager config.status 0.9.1.90
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
@@ -25316,6 +25485,8 @@ else
 	echo PPP support: no
 fi
 
+echo libnl version: ${libnl_version}
+
 echo
 echo Building documentation: ${with_docs}
 echo Building tests: ${with_tests}
diff --git a/configure.ac b/configure.ac
index c557c6be..117dd918 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,9 +3,10 @@ AC_PREREQ([2.63])
 dnl The NM version number
 m4_define([nm_major_version], [0])
 m4_define([nm_minor_version], [9])
-m4_define([nm_micro_version], [0])
+m4_define([nm_micro_version], [1])
+m4_define([nm_nano_version],  [90])
 m4_define([nm_version],
-          [nm_major_version.nm_minor_version.nm_micro_version])
+          [nm_major_version.nm_minor_version.nm_micro_version.nm_nano_version])
 
 AC_INIT([NetworkManager], [nm_version],
         [http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager],
@@ -312,10 +313,43 @@ else
 fi
 AC_DEFINE_UNQUOTED(NO_CONSOLEKIT, $no_ck, [Define to disable use of ConsoleKit])
 
-PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8)
+have_libnl="no"
+PKG_CHECK_MODULES(LIBNL1, libnl-1 >= 1.0-pre8, [have_libnl1=yes], [have_libnl1=no])
+if (test "${have_libnl1}" = "yes"); then
+	AC_DEFINE(HAVE_LIBNL1, 1, [Define if you require libnl-1 legacy support])
+	LIBNL_CFLAGS="$LIBNL1_CFLAGS"
+	LIBNL_LIBS="$LIBNL1_LIBS"
+	libnl_version="1"
+	have_libnl="yes"
+fi
+
+PKG_CHECK_MODULES(LIBNL2, libnl-2.0, [have_libnl2=yes], [have_libnl2=no])
+if (test "${have_libnl2}" = "yes"); then
+	AC_DEFINE(HAVE_LIBNL2, 1, [Define if you require specific libnl-2 support])
+	LIBNL_CFLAGS="$LIBNL2_CFLAGS"
+	LIBNL_LIBS="$LIBNL2_LIBS"
+	libnl_version="2"
+	have_libnl="yes"
+fi
+
+PKG_CHECK_MODULES(LIBNL3, libnl-3.0, [have_libnl2=yes], [have_libnl2=no])
+if (test "${have_libnl2}" = "yes"); then
+	AC_DEFINE(HAVE_LIBNL3, 1, [Define if you require specific libnl-3 support])
+	LIBNL_CFLAGS="$LIBNL3_CFLAGS"
+	LIBNL_LIBS="$LIBNL3_LIBS"
+	libnl_version="3"
+	have_libnl="yes"
+fi
+
+if (test "${have_libnl}" = "no"); then
+	AC_MSG_ERROR([libnl development header are required])
+fi
 AC_SUBST(LIBNL_CFLAGS)
 AC_SUBST(LIBNL_LIBS)
-NM_LIBNL_CHECK
+
+if (test "${libnl_version}" = "1"); then
+	NM_LIBNL_CHECK
+fi
 
 PKG_CHECK_MODULES(UUID, uuid)
 AC_SUBST(UUID_CFLAGS)
@@ -738,6 +772,8 @@ else
 	echo PPP support: no
 fi
 
+echo libnl version: ${libnl_version}
+
 echo
 echo Building documentation: ${with_docs}
 echo Building tests: ${with_tests}
diff --git a/data/Makefile.in b/data/Makefile.in
index a5061e00..d09cbd98 100644
--- a/data/Makefile.in
+++ b/data/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 91ce98e5..9a5b96c2 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -192,6 +192,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/docs/api/Makefile.in b/docs/api/Makefile.in
index 47874caf..ed69a17b 100644
--- a/docs/api/Makefile.in
+++ b/docs/api/Makefile.in
@@ -196,6 +196,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/docs/api/html/NetworkManager.devhelp b/docs/api/html/NetworkManager.devhelp
index 225718a4..4a5c1038 100644
--- a/docs/api/html/NetworkManager.devhelp
+++ b/docs/api/html/NetworkManager.devhelp
@@ -4,23 +4,23 @@
   <chapters>
     <sub name="D-Bus API Reference" link="ref-dbus.html"/>
     <sub name="Network Configuration Setting Specification" link="ref-settings.html">
-      <sub name="Configuration Settings" link="ref-settings.html#id499631"/>
+      <sub name="Configuration Settings" link="ref-settings.html#id433480"/>
       <sub name="Secret flag types" link="secrets-flags.html"/>
     </sub>
     <sub name="Migrating from NetworkManager 0.8 to NetworkManager 0.9" link="ref-migrating.html">
-      <sub name="Architecture and D-Bus API Changes in 0.9" link="ref-migrating.html#id515244">
-        <sub name="Elimination of the User Settings Service" link="ref-migrating.html#id506888"/>
-        <sub name="User Secret Agents" link="ref-migrating.html#id490940"/>
-        <sub name="Settings Service Interface Changes" link="ref-migrating.html#id478937"/>
-        <sub name="Connection Object Interface Changes" link="ref-migrating.html#id496154"/>
-        <sub name="Permissions Methods Consolidation" link="ref-migrating.html#id469504"/>
-        <sub name="AddConnection Returns Object Path of New Connection" link="ref-migrating.html#id485456"/>
-        <sub name="Support for WiMAX Devices" link="ref-migrating.html#id490040"/>
-        <sub name="New Device States" link="ref-migrating.html#id507718"/>
-        <sub name="New Active Connection State" link="ref-migrating.html#id515265"/>
-        <sub name="Consolidated Modem Devices" link="ref-migrating.html#id515394"/>
-        <sub name="Secret Property Flags" link="ref-migrating.html#id479874"/>
-        <sub name="Deprecated Methods Removed" link="ref-migrating.html#id474466"/>
+      <sub name="Architecture and D-Bus API Changes in 0.9" link="ref-migrating.html#id449094">
+        <sub name="Elimination of the User Settings Service" link="ref-migrating.html#id440737"/>
+        <sub name="User Secret Agents" link="ref-migrating.html#id424790"/>
+        <sub name="Settings Service Interface Changes" link="ref-migrating.html#id412786"/>
+        <sub name="Connection Object Interface Changes" link="ref-migrating.html#id430004"/>
+        <sub name="Permissions Methods Consolidation" link="ref-migrating.html#id403354"/>
+        <sub name="AddConnection Returns Object Path of New Connection" link="ref-migrating.html#id419306"/>
+        <sub name="Support for WiMAX Devices" link="ref-migrating.html#id423890"/>
+        <sub name="New Device States" link="ref-migrating.html#id441568"/>
+        <sub name="New Active Connection State" link="ref-migrating.html#id449114"/>
+        <sub name="Consolidated Modem Devices" link="ref-migrating.html#id449243"/>
+        <sub name="Secret Property Flags" link="ref-migrating.html#id413724"/>
+        <sub name="Deprecated Methods Removed" link="ref-migrating.html#id408316"/>
       </sub>
     </sub>
     <sub name="Index" link="ix01.html"/>
diff --git a/docs/api/html/NetworkManager.devhelp2 b/docs/api/html/NetworkManager.devhelp2
index e5538797..c67adae7 100644
--- a/docs/api/html/NetworkManager.devhelp2
+++ b/docs/api/html/NetworkManager.devhelp2
@@ -4,23 +4,23 @@
   <chapters>
     <sub name="D-Bus API Reference" link="ref-dbus.html"/>
     <sub name="Network Configuration Setting Specification" link="ref-settings.html">
-      <sub name="Configuration Settings" link="ref-settings.html#id499631"/>
+      <sub name="Configuration Settings" link="ref-settings.html#id433480"/>
       <sub name="Secret flag types" link="secrets-flags.html"/>
     </sub>
     <sub name="Migrating from NetworkManager 0.8 to NetworkManager 0.9" link="ref-migrating.html">
-      <sub name="Architecture and D-Bus API Changes in 0.9" link="ref-migrating.html#id515244">
-        <sub name="Elimination of the User Settings Service" link="ref-migrating.html#id506888"/>
-        <sub name="User Secret Agents" link="ref-migrating.html#id490940"/>
-        <sub name="Settings Service Interface Changes" link="ref-migrating.html#id478937"/>
-        <sub name="Connection Object Interface Changes" link="ref-migrating.html#id496154"/>
-        <sub name="Permissions Methods Consolidation" link="ref-migrating.html#id469504"/>
-        <sub name="AddConnection Returns Object Path of New Connection" link="ref-migrating.html#id485456"/>
-        <sub name="Support for WiMAX Devices" link="ref-migrating.html#id490040"/>
-        <sub name="New Device States" link="ref-migrating.html#id507718"/>
-        <sub name="New Active Connection State" link="ref-migrating.html#id515265"/>
-        <sub name="Consolidated Modem Devices" link="ref-migrating.html#id515394"/>
-        <sub name="Secret Property Flags" link="ref-migrating.html#id479874"/>
-        <sub name="Deprecated Methods Removed" link="ref-migrating.html#id474466"/>
+      <sub name="Architecture and D-Bus API Changes in 0.9" link="ref-migrating.html#id449094">
+        <sub name="Elimination of the User Settings Service" link="ref-migrating.html#id440737"/>
+        <sub name="User Secret Agents" link="ref-migrating.html#id424790"/>
+        <sub name="Settings Service Interface Changes" link="ref-migrating.html#id412786"/>
+        <sub name="Connection Object Interface Changes" link="ref-migrating.html#id430004"/>
+        <sub name="Permissions Methods Consolidation" link="ref-migrating.html#id403354"/>
+        <sub name="AddConnection Returns Object Path of New Connection" link="ref-migrating.html#id419306"/>
+        <sub name="Support for WiMAX Devices" link="ref-migrating.html#id423890"/>
+        <sub name="New Device States" link="ref-migrating.html#id441568"/>
+        <sub name="New Active Connection State" link="ref-migrating.html#id449114"/>
+        <sub name="Consolidated Modem Devices" link="ref-migrating.html#id449243"/>
+        <sub name="Secret Property Flags" link="ref-migrating.html#id413724"/>
+        <sub name="Deprecated Methods Removed" link="ref-migrating.html#id408316"/>
       </sub>
     </sub>
     <sub name="Index" link="ix01.html"/>
diff --git a/docs/api/html/index.html b/docs/api/html/index.html
index c734b922..bc12bb5c 100644
--- a/docs/api/html/index.html
+++ b/docs/api/html/index.html
@@ -22,11 +22,11 @@
 	    <code class="email">&lt;<a class="email" href="mailto:dcbw@redhat.com">dcbw@redhat.com</a>&gt;</code><br>
 	  </p></div></div>
 </div></div></div>
-<div><p class="releaseinfo">Version 0.9.0
+<div><p class="releaseinfo">Version 0.9.1.90
 </p></div>
 <div><p class="copyright">Copyright © 2011 The NetworkManager Authors</p></div>
 <div><div class="legalnotice">
-<a name="id429511"></a><p>
+<a name="id363361"></a><p>
 	Permission is granted to copy, distribute and/or modify this
 	document under the terms of the <em class="citetitle">GNU Free
 	Documentation License</em>, Version 1.1 or any later
@@ -61,25 +61,25 @@
 <dt><span class="chapter"><a href="ref-dbus.html">D-Bus API Reference</a></span></dt>
 <dt><span class="chapter"><a href="ref-settings.html">Network Configuration Setting Specification</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="ref-settings.html#id499631">Configuration Settings</a></span></dt>
+<dt><span class="section"><a href="ref-settings.html#id433480">Configuration Settings</a></span></dt>
 <dt><span class="section"><a href="secrets-flags.html">Secret flag types</a></span></dt>
 </dl></dd>
 <dt><span class="chapter"><a href="ref-migrating.html">Migrating from NetworkManager 0.8 to NetworkManager 0.9</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="ref-migrating.html#id515244">Architecture and D-Bus API Changes in 0.9</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449094">Architecture and D-Bus API Changes in 0.9</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="ref-migrating.html#id506888">Elimination of the User Settings Service</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id490940">User Secret Agents</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id478937">Settings Service Interface Changes</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id496154">Connection Object Interface Changes</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id469504">Permissions Methods Consolidation</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id485456">AddConnection Returns Object Path of New Connection</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id490040">Support for WiMAX Devices</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id507718">New Device States</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id515265">New Active Connection State</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id515394">Consolidated Modem Devices</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id479874">Secret Property Flags</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id474466">Deprecated Methods Removed</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id440737">Elimination of the User Settings Service</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id424790">User Secret Agents</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id412786">Settings Service Interface Changes</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id430004">Connection Object Interface Changes</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id403354">Permissions Methods Consolidation</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id419306">AddConnection Returns Object Path of New Connection</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id423890">Support for WiMAX Devices</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id441568">New Device States</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449114">New Active Connection State</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449243">Consolidated Modem Devices</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id413724">Secret Property Flags</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id408316">Deprecated Methods Removed</a></span></dt>
 </dl></dd>
 </dl></dd>
 <dt><span class="index"><a href="ix01.html">Index</a></span></dt>
diff --git a/docs/api/html/ix01.html b/docs/api/html/ix01.html
index ffcd2110..92a951b4 100644
--- a/docs/api/html/ix01.html
+++ b/docs/api/html/ix01.html
@@ -21,7 +21,7 @@
 </tr></table>
 <div class="index">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="id459403"></a>Index</h2></div></div></div>
+<a name="id393253"></a>Index</h2></div></div></div>
 <div class="index"></div>
 </div>
 <div class="footer">
diff --git a/docs/api/html/ref-migrating.html b/docs/api/html/ref-migrating.html
index a3221b04..ad4813eb 100644
--- a/docs/api/html/ref-migrating.html
+++ b/docs/api/html/ref-migrating.html
@@ -23,20 +23,20 @@
 <div class="titlepage"><div><div><h2 class="title">
 <a name="ref-migrating"></a>Migrating from NetworkManager 0.8 to NetworkManager 0.9</h2></div></div></div>
 <div class="toc"><dl>
-<dt><span class="section"><a href="ref-migrating.html#id515244">Architecture and D-Bus API Changes in 0.9</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449094">Architecture and D-Bus API Changes in 0.9</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="ref-migrating.html#id506888">Elimination of the User Settings Service</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id490940">User Secret Agents</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id478937">Settings Service Interface Changes</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id496154">Connection Object Interface Changes</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id469504">Permissions Methods Consolidation</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id485456">AddConnection Returns Object Path of New Connection</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id490040">Support for WiMAX Devices</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id507718">New Device States</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id515265">New Active Connection State</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id515394">Consolidated Modem Devices</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id479874">Secret Property Flags</a></span></dt>
-<dt><span class="section"><a href="ref-migrating.html#id474466">Deprecated Methods Removed</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id440737">Elimination of the User Settings Service</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id424790">User Secret Agents</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id412786">Settings Service Interface Changes</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id430004">Connection Object Interface Changes</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id403354">Permissions Methods Consolidation</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id419306">AddConnection Returns Object Path of New Connection</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id423890">Support for WiMAX Devices</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id441568">New Device States</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449114">New Active Connection State</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id449243">Consolidated Modem Devices</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id413724">Secret Property Flags</a></span></dt>
+<dt><span class="section"><a href="ref-migrating.html#id408316">Deprecated Methods Removed</a></span></dt>
 </dl></dd>
 </dl></div>
 <p>
@@ -50,14 +50,14 @@
   </p>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id515244"></a>Architecture and D-Bus API Changes in 0.9</h2></div></div></div>
+<a name="id449094"></a>Architecture and D-Bus API Changes in 0.9</h2></div></div></div>
 <p>
       This section details the architectural and D-Bus API changes in
       NetworkManager 0.9.
     </p>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id506888"></a>Elimination of the User Settings Service</h3></div></div></div>
+<a name="id440737"></a>Elimination of the User Settings Service</h3></div></div></div>
 <p>
       Previously there were two "settings services", or D-Bus services that
       provided and saved network configuration information.  NetworkManager
@@ -103,7 +103,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id490940"></a>User Secret Agents</h3></div></div></div>
+<a name="id424790"></a>User Secret Agents</h3></div></div></div>
 <p>
       Even with the elimination of the user settings service, in some cases it
       is still desirable to store secrets in the user's session and not in
@@ -152,7 +152,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id478937"></a>Settings Service Interface Changes</h3></div></div></div>
+<a name="id412786"></a>Settings Service Interface Changes</h3></div></div></div>
 <p>
       With the elimination of the user settings service, the old
       <code class="literal">org.freedesktop.NetworkManagerUserSettings</code> and
@@ -188,7 +188,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id496154"></a>Connection Object Interface Changes</h3></div></div></div>
+<a name="id430004"></a>Connection Object Interface Changes</h3></div></div></div>
 <p>
       Consistent with the interface changes to the Settings object, the
       Connection object's D-Bus interface has changed to
@@ -222,7 +222,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id469504"></a>Permissions Methods Consolidation</h3></div></div></div>
+<a name="id403354"></a>Permissions Methods Consolidation</h3></div></div></div>
 <p>
       Previously there were two D-Bus method calls to retrieve the list of
       operations that a user client could perform, and two signals notifying
@@ -254,7 +254,7 @@
       are now string-based permissions.  The mapping is as follows:
       </p>
 <div class="table">
-<a name="id502282"></a><p class="title"><b>Table 17. </b></p>
+<a name="id436132"></a><p class="title"><b>Table 17. </b></p>
 <div class="table-contents"><table border="1">
 <colgroup>
 <col>
@@ -305,7 +305,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id485456"></a>AddConnection Returns Object Path of New Connection</h3></div></div></div>
+<a name="id419306"></a>AddConnection Returns Object Path of New Connection</h3></div></div></div>
 <p>
       The <a class="ulink" href="spec.html#org.freedesktop.NetworkManager.Settings" target="_top">
       <code class="literal">org.freedesktop.NetworkManager.Settings.AddConnection</code>
@@ -323,7 +323,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id490040"></a>Support for WiMAX Devices</h3></div></div></div>
+<a name="id423890"></a>Support for WiMAX Devices</h3></div></div></div>
 <p>
       NetworkManager now supports Intel WiMAX mobile broadband devices.  A
       corresponding device type (<code class="literal">NM_DEVICE_TYPE_WIMAX</code>) and
@@ -346,7 +346,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id507718"></a>New Device States</h3></div></div></div>
+<a name="id441568"></a>New Device States</h3></div></div></div>
 <p>
       A few <a class="ulink" href="spec.html#type-NM_DEVICE_STATE" target="_top">new device states</a>
       have been added, and all device states have been renumbered for flexibility.
@@ -361,7 +361,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id515265"></a>New Active Connection State</h3></div></div></div>
+<a name="id449114"></a>New Active Connection State</h3></div></div></div>
 <p>
       Along with the new device states, an
       <a class="ulink" href="spec.html#type-NM_ACTIVE_CONNECTION_STATE" target="_top">additional
@@ -377,7 +377,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id515394"></a>Consolidated Modem Devices</h3></div></div></div>
+<a name="id449243"></a>Consolidated Modem Devices</h3></div></div></div>
 <p>
       Many new mobile broadband devices support multiple access families, like
       Qualcomm Gobi cards (CDMA/EVDO and GSM/UMTS), or multi-mode EVDO/LTE
@@ -413,7 +413,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id479874"></a>Secret Property Flags</h3></div></div></div>
+<a name="id413724"></a>Secret Property Flags</h3></div></div></div>
 <p>
       In the Connection object's configuration properties, each setting's secret
       properties (like WiFi passphrases, or public key passwords, etc) now has
@@ -422,7 +422,7 @@
       following values:
       </p>
 <div class="table">
-<a name="id479882"></a><p class="title"><b>Table 18. </b></p>
+<a name="id413732"></a><p class="title"><b>Table 18. </b></p>
 <div class="table-contents"><table border="1">
 <colgroup>
 <col>
@@ -484,7 +484,7 @@
 </div>
 <div class="section">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id474466"></a>Deprecated Methods Removed</h3></div></div></div>
+<a name="id408316"></a>Deprecated Methods Removed</h3></div></div></div>
 <p>
       A few methods and signals of the <code class="literal">org.freedesktop.NetworkManager</code>
       interface deprecated in version 0.7 have been removed.  All the
@@ -494,7 +494,7 @@
       their replacements:
       </p>
 <div class="table">
-<a name="id474480"></a><p class="title"><b>Table 19. </b></p>
+<a name="id408330"></a><p class="title"><b>Table 19. </b></p>
 <div class="table-contents"><table border="1">
 <colgroup>
 <col>
diff --git a/docs/api/html/ref-settings.html b/docs/api/html/ref-settings.html
index 5db0ccd8..d062b73f 100644
--- a/docs/api/html/ref-settings.html
+++ b/docs/api/html/ref-settings.html
@@ -23,7 +23,7 @@
 <div class="titlepage"><div><div><h2 class="title">
 <a name="ref-settings"></a>Network Configuration Setting Specification</h2></div></div></div>
 <div class="toc"><dl>
-<dt><span class="section"><a href="ref-settings.html#id499631">Configuration Settings</a></span></dt>
+<dt><span class="section"><a href="ref-settings.html#id433480">Configuration Settings</a></span></dt>
 <dt><span class="section"><a href="secrets-flags.html">Secret flag types</a></span></dt>
 </dl></div>
 <p>
@@ -35,11 +35,11 @@
     </p>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id499631"></a>Configuration Settings</h2></div></div></div>
+<a name="id433480"></a>Configuration Settings</h2></div></div></div>
 <p>
 </p>
 <div class="table">
-<a name="id502860"></a><p class="title"><b>Table 1. 802-1x setting</b></p>
+<a name="id436709"></a><p class="title"><b>Table 1. 802-1x setting</b></p>
 <div class="table-contents"><table summary="802-1x setting" border="1">
 <colgroup>
 <col>
@@ -228,7 +228,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id486852"></a><p class="title"><b>Table 2. bluetooth setting</b></p>
+<a name="id420701"></a><p class="title"><b>Table 2. bluetooth setting</b></p>
 <div class="table-contents"><table summary="bluetooth setting" border="1">
 <colgroup>
 <col>
@@ -267,7 +267,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id486984"></a><p class="title"><b>Table 3. cdma setting</b></p>
+<a name="id420834"></a><p class="title"><b>Table 3. cdma setting</b></p>
 <div class="table-contents"><table summary="cdma setting" border="1">
 <colgroup>
 <col>
@@ -318,7 +318,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id487182"></a><p class="title"><b>Table 4. connection setting</b></p>
+<a name="id421032"></a><p class="title"><b>Table 4. connection setting</b></p>
 <div class="table-contents"><table summary="connection setting" border="1">
 <colgroup>
 <col>
@@ -387,7 +387,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id487483"></a><p class="title"><b>Table 5. gsm setting</b></p>
+<a name="id421333"></a><p class="title"><b>Table 5. gsm setting</b></p>
 <div class="table-contents"><table summary="gsm setting" border="1">
 <colgroup>
 <col>
@@ -480,7 +480,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id487908"></a><p class="title"><b>Table 6. ipv4 setting</b></p>
+<a name="id421758"></a><p class="title"><b>Table 6. ipv4 setting</b></p>
 <div class="table-contents"><table summary="ipv4 setting" border="1">
 <colgroup>
 <col>
@@ -579,7 +579,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id516867"></a><p class="title"><b>Table 7. ipv6 setting</b></p>
+<a name="id450716"></a><p class="title"><b>Table 7. ipv6 setting</b></p>
 <div class="table-contents"><table summary="ipv6 setting" border="1">
 <colgroup>
 <col>
@@ -660,7 +660,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id517185"></a><p class="title"><b>Table 8. 802-11-olpc-mesh setting</b></p>
+<a name="id451035"></a><p class="title"><b>Table 8. 802-11-olpc-mesh setting</b></p>
 <div class="table-contents"><table summary="802-11-olpc-mesh setting" border="1">
 <colgroup>
 <col>
@@ -705,7 +705,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id517323"></a><p class="title"><b>Table 9. ppp setting</b></p>
+<a name="id451173"></a><p class="title"><b>Table 9. ppp setting</b></p>
 <div class="table-contents"><table summary="ppp setting" border="1">
 <colgroup>
 <col>
@@ -840,7 +840,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id517853"></a><p class="title"><b>Table 10. pppoe setting</b></p>
+<a name="id451703"></a><p class="title"><b>Table 10. pppoe setting</b></p>
 <div class="table-contents"><table summary="pppoe setting" border="1">
 <colgroup>
 <col>
@@ -891,7 +891,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id518018"></a><p class="title"><b>Table 11. serial setting</b></p>
+<a name="id451868"></a><p class="title"><b>Table 11. serial setting</b></p>
 <div class="table-contents"><table summary="serial setting" border="1">
 <colgroup>
 <col>
@@ -948,7 +948,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id518231"></a><p class="title"><b>Table 12. vpn setting</b></p>
+<a name="id452080"></a><p class="title"><b>Table 12. vpn setting</b></p>
 <div class="table-contents"><table summary="vpn setting" border="1">
 <colgroup>
 <col>
@@ -999,7 +999,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id518437"></a><p class="title"><b>Table 13. wimax setting</b></p>
+<a name="id452286"></a><p class="title"><b>Table 13. wimax setting</b></p>
 <div class="table-contents"><table summary="wimax setting" border="1">
 <colgroup>
 <col>
@@ -1038,7 +1038,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id518575"></a><p class="title"><b>Table 14. 802-3-ethernet setting</b></p>
+<a name="id452425"></a><p class="title"><b>Table 14. 802-3-ethernet setting</b></p>
 <div class="table-contents"><table summary="802-3-ethernet setting" border="1">
 <colgroup>
 <col>
@@ -1131,7 +1131,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id519016"></a><p class="title"><b>Table 15. 802-11-wireless setting</b></p>
+<a name="id452865"></a><p class="title"><b>Table 15. 802-11-wireless setting</b></p>
 <div class="table-contents"><table summary="802-11-wireless setting" border="1">
 <colgroup>
 <col>
@@ -1236,7 +1236,7 @@
 <p><br class="table-break">
 </p>
 <div class="table">
-<a name="id519524"></a><p class="title"><b>Table 16. 802-11-wireless-security setting</b></p>
+<a name="id453374"></a><p class="title"><b>Table 16. 802-11-wireless-security setting</b></p>
 <div class="table-contents"><table summary="802-11-wireless-security setting" border="1">
 <colgroup>
 <col>
diff --git a/docs/api/html/spec.html b/docs/api/html/spec.html
index c8abf6ca..9f652756 100644
--- a/docs/api/html/spec.html
+++ b/docs/api/html/spec.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ascii" /><title>NetworkManager D-Bus Interface Specification version 0.9.0</title><style type="text/css">
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ascii" /><title>NetworkManager D-Bus Interface Specification version 0.9.1.90</title><style type="text/css">
 
           body {
             font-family: sans-serif;
@@ -98,7 +98,7 @@
             margin-right: 4em;
           }
 
-        </style></head><body><h1 class="topbox">NetworkManager D-Bus Interface Specification</h1><h2>Version 0.9.0</h2><div>Copyright (C) 2008 - 2011 Red Hat, Inc.</div><div>Copyright (C) 2008 - 2009 Novell, Inc.</div><div class="license">
+        </style></head><body><h1 class="topbox">NetworkManager D-Bus Interface Specification</h1><h2>Version 0.9.1.90</h2><div>Copyright (C) 2008 - 2011 Red Hat, Inc.</div><div>Copyright (C) 2008 - 2009 Novell, Inc.</div><div class="license">
 <p>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
@@ -112,7 +112,7 @@ General Public License for more details.</p>
 <p>You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
-</div><h2>Interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul>
+</div><h2>Interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.SecretAgent">org.freedesktop.NetworkManager.SecretAgent</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul>
   <h1><a name="org.freedesktop.NetworkManager" id="org.freedesktop.NetworkManager"></a>org.freedesktop.NetworkManager</h1><h2>Methods:</h2><div class="method"><h3><a name="org.freedesktop.NetworkManager.GetDevices" id="org.freedesktop.NetworkManager.GetDevices">GetDevices</a> (
         
         ) &#8594;
@@ -1169,6 +1169,129 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
         unregistered when they disconnect from D-Bus.
       </div></div><p>Interface has no signals.</p><p>Interface has no properties.</p>
 
+
+    <h1><a name="org.freedesktop.NetworkManager.SecretAgent" id="org.freedesktop.NetworkManager.SecretAgent"></a>org.freedesktop.NetworkManager.SecretAgent</h1>
+            Private D-Bus interface used by secret agents that store and provide
+            secrets to NetworkManager.  If an agent provides secrets to
+            NetworkManager as part of connection creation, and the some of those
+            secrets are "agent owned" the agent should store those secrets
+            itself and should not expect its SaveSecrets() method to be called.
+            SaveSecrets() will be called eg if some program other than the
+            agent itself (like a connection editor) changes the secrets out of
+            band.
+        <h2>Methods:</h2><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.GetSecrets" id="org.freedesktop.NetworkManager.SecretAgent.GetSecrets">GetSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path, s: setting_name, as: hints, u: flags
+        ) &#8594;
+        a{sa{sv}}</h3><div class="docstring">
+                Retrieve and return stored secrets, if any, or request new
+                secrets from the agent's user.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the connection for which
+                    secrets are being requested.  This may contain system-owned
+                    secrets if the agent has successfully authenticated to
+                    modify system network settings and the GetSecrets request
+                    flags allow user interaction.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which secrets are being
+                    requested.
+                </dd><dt><code>setting_name</code> -
+      <code>s</code></dt><dd>
+                    Setting name for which secrets are being requested.
+                </dd><dt><code>hints</code> -
+      <code>as</code></dt><dd>
+                    Array of strings of key names in the requested setting for
+                    which NetworkManager thinks a secrets may be required,
+                    and/or well-known identifiers and data that may be useful
+                    to the client in processing the secrets request. The Agent
+                    should return any secrets it has, or that it thinks are
+                    required, regardless of what hints NetworkManager sends
+                    in this request.
+                </dd><dt><code>flags</code> -
+      <code>u</code>
+      (<a xmlns="" href="#type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a>)
+    </dt><dd>
+                    Flags which modify the behavior of the secrets request.
+                    If true, new secrets are assumed to be invalid or incorrect,
+                    and the agent should ask the user for new secrets.  If false,
+                    existing secrets should be retrieved from storage and 
+                    returned without interrupting the user.
+                </dd></dl></div><div><h4>Returns</h4><dl><dt><code>secrets</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing secrets.  Each setting MUST
+                    contain at least the 'name' field, containing the name of
+                    the setting, and one or more secrets.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets" id="org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets">CancelGetSecrets</a> (
+        o: connection_path, s: setting_name
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Cancel a pending GetSecrets request for secrets of the given
+                connection.  Any matching request should be canceled.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which, if secrets are being
+                    requested, the request should be canceled.
+                </dd><dt><code>setting_name</code> -
+      <code>s</code></dt><dd>
+                    Setting name for which secrets for this connection were
+                    originally being requested.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.SaveSecrets" id="org.freedesktop.NetworkManager.SecretAgent.SaveSecrets">SaveSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Save given secrets to backing storage.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the entire connection
+                    (including secrets), for which the agent should save the
+                    secrets to backing storage.  This method will not be called
+                    when the agent itself is the process creating or updating
+                    a connection; in that case the agent is assumed to have
+                    already saved those secrets since it had them already.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which the agent should
+                    save secrets to backing storage.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets" id="org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets">DeleteSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Delete secrets from backing storage.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the connection properties
+                    (sans secrets), for which the agent should delete the
+                    secrets from backing storage.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which the agent should
+                    delete secrets from backing storage.
+                </dd></dl></div></div><p>Interface has no signals.</p><p>Interface has no properties.</p><h2>Sets of flags:</h2><h3 xmlns=""><a name="type-NM_SECRET_AGENT_GET_SECRETS_FLAGS" id="type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a></h3>
+            Flags modifying the behavior of GetSecrets request.
+          <dl><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0</code></dt><dd>
+              No special behavior; by default no user interaction is allowed and
+              requests for secrets are fulfilled from persistent storage, or
+              if no secrets are available an error is returned.
+            </dd><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1</code></dt><dd>
+              Allows the request to interact with the user, possibly prompting
+              via UI for secrets if any are required, or if none are found in
+              persistent storage.
+            </dd><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2</code></dt><dd>
+              Explicitly prompt for new secrets from the user.  This flag
+              signals that NetworkManager thinks any existing secrets are
+              invalid or wrong.  This flag implies that interaction is allowed.
+            </dd></dl>
+
+
   <h1><a name="org.freedesktop.NetworkManager.VPN.Connection" id="org.freedesktop.NetworkManager.VPN.Connection"></a>org.freedesktop.NetworkManager.VPN.Connection</h1>
       Represents an active connection to a Virtual Private Network.
     <p>Interface has no methods.</p><h2>Signals:</h2><div class="signal"><h3><a name="org.freedesktop.NetworkManager.VPN.Connection.PropertiesChanged" id="org.freedesktop.NetworkManager.VPN.Connection.PropertiesChanged">PropertiesChanged</a> (
@@ -1379,7 +1502,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.BadArguments" id="org.freedesktop.NetworkManager.VPN.Error.BadArguments"></a>org.freedesktop.NetworkManager.VPN.Error.BadArguments</h2>Invalid arguments were passed with the request.  FIXME: too general.
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.LaunchFailed" id="org.freedesktop.NetworkManager.VPN.Error.LaunchFailed"></a>org.freedesktop.NetworkManager.VPN.Error.LaunchFailed</h2>A binary providing the service failed to launch.
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid" id="org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid"></a>org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid</h2>The request could not be processed because the VPN connection settings were invalid.
-<h1>Index</h1><h2>Index of interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul><h2>Index of types</h2><ul><li><code><a href="#type-NM_802_11_AP_FLAGS">NM_802_11_AP_FLAGS</a></code>
+<h1>Index</h1><h2>Index of interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.SecretAgent">org.freedesktop.NetworkManager.SecretAgent</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul><h2>Index of types</h2><ul><li><code><a href="#type-NM_802_11_AP_FLAGS">NM_802_11_AP_FLAGS</a></code>
     - u</li><li><code><a href="#type-NM_802_11_AP_SEC">NM_802_11_AP_SEC</a></code>
     - u</li><li><code><a href="#type-NM_802_11_DEVICE_CAP">NM_802_11_DEVICE_CAP</a></code>
     - u</li><li><code><a href="#type-NM_802_11_MODE">NM_802_11_MODE</a></code>
@@ -1390,6 +1513,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
     - u</li><li><code><a href="#type-NM_DEVICE_STATE">NM_DEVICE_STATE</a></code>
     - u</li><li><code><a href="#type-NM_DEVICE_STATE_REASON">NM_DEVICE_STATE_REASON</a></code>
     - u</li><li><code><a href="#type-NM_DEVICE_TYPE">NM_DEVICE_TYPE</a></code>
+    - u</li><li><code><a href="#type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a></code>
     - u</li><li><code><a href="#type-NM_STATE">NM_STATE</a></code>
     - u</li><li><code><a href="#type-NM_VPN_CONNECTION_STATE">NM_VPN_CONNECTION_STATE</a></code>
     - u</li><li><code><a href="#type-NM_VPN_CONNECTION_STATE_REASON">NM_VPN_CONNECTION_STATE_REASON</a></code>
diff --git a/docs/api/spec.html b/docs/api/spec.html
index c8abf6ca..9f652756 100644
--- a/docs/api/spec.html
+++ b/docs/api/spec.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ascii" /><title>NetworkManager D-Bus Interface Specification version 0.9.0</title><style type="text/css">
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ascii" /><title>NetworkManager D-Bus Interface Specification version 0.9.1.90</title><style type="text/css">
 
           body {
             font-family: sans-serif;
@@ -98,7 +98,7 @@
             margin-right: 4em;
           }
 
-        </style></head><body><h1 class="topbox">NetworkManager D-Bus Interface Specification</h1><h2>Version 0.9.0</h2><div>Copyright (C) 2008 - 2011 Red Hat, Inc.</div><div>Copyright (C) 2008 - 2009 Novell, Inc.</div><div class="license">
+        </style></head><body><h1 class="topbox">NetworkManager D-Bus Interface Specification</h1><h2>Version 0.9.1.90</h2><div>Copyright (C) 2008 - 2011 Red Hat, Inc.</div><div>Copyright (C) 2008 - 2009 Novell, Inc.</div><div class="license">
 <p>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
@@ -112,7 +112,7 @@ General Public License for more details.</p>
 <p>You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
-</div><h2>Interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul>
+</div><h2>Interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.SecretAgent">org.freedesktop.NetworkManager.SecretAgent</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul>
   <h1><a name="org.freedesktop.NetworkManager" id="org.freedesktop.NetworkManager"></a>org.freedesktop.NetworkManager</h1><h2>Methods:</h2><div class="method"><h3><a name="org.freedesktop.NetworkManager.GetDevices" id="org.freedesktop.NetworkManager.GetDevices">GetDevices</a> (
         
         ) &#8594;
@@ -1169,6 +1169,129 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
         unregistered when they disconnect from D-Bus.
       </div></div><p>Interface has no signals.</p><p>Interface has no properties.</p>
 
+
+    <h1><a name="org.freedesktop.NetworkManager.SecretAgent" id="org.freedesktop.NetworkManager.SecretAgent"></a>org.freedesktop.NetworkManager.SecretAgent</h1>
+            Private D-Bus interface used by secret agents that store and provide
+            secrets to NetworkManager.  If an agent provides secrets to
+            NetworkManager as part of connection creation, and the some of those
+            secrets are "agent owned" the agent should store those secrets
+            itself and should not expect its SaveSecrets() method to be called.
+            SaveSecrets() will be called eg if some program other than the
+            agent itself (like a connection editor) changes the secrets out of
+            band.
+        <h2>Methods:</h2><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.GetSecrets" id="org.freedesktop.NetworkManager.SecretAgent.GetSecrets">GetSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path, s: setting_name, as: hints, u: flags
+        ) &#8594;
+        a{sa{sv}}</h3><div class="docstring">
+                Retrieve and return stored secrets, if any, or request new
+                secrets from the agent's user.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the connection for which
+                    secrets are being requested.  This may contain system-owned
+                    secrets if the agent has successfully authenticated to
+                    modify system network settings and the GetSecrets request
+                    flags allow user interaction.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which secrets are being
+                    requested.
+                </dd><dt><code>setting_name</code> -
+      <code>s</code></dt><dd>
+                    Setting name for which secrets are being requested.
+                </dd><dt><code>hints</code> -
+      <code>as</code></dt><dd>
+                    Array of strings of key names in the requested setting for
+                    which NetworkManager thinks a secrets may be required,
+                    and/or well-known identifiers and data that may be useful
+                    to the client in processing the secrets request. The Agent
+                    should return any secrets it has, or that it thinks are
+                    required, regardless of what hints NetworkManager sends
+                    in this request.
+                </dd><dt><code>flags</code> -
+      <code>u</code>
+      (<a xmlns="" href="#type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a>)
+    </dt><dd>
+                    Flags which modify the behavior of the secrets request.
+                    If true, new secrets are assumed to be invalid or incorrect,
+                    and the agent should ask the user for new secrets.  If false,
+                    existing secrets should be retrieved from storage and 
+                    returned without interrupting the user.
+                </dd></dl></div><div><h4>Returns</h4><dl><dt><code>secrets</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing secrets.  Each setting MUST
+                    contain at least the 'name' field, containing the name of
+                    the setting, and one or more secrets.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets" id="org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets">CancelGetSecrets</a> (
+        o: connection_path, s: setting_name
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Cancel a pending GetSecrets request for secrets of the given
+                connection.  Any matching request should be canceled.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which, if secrets are being
+                    requested, the request should be canceled.
+                </dd><dt><code>setting_name</code> -
+      <code>s</code></dt><dd>
+                    Setting name for which secrets for this connection were
+                    originally being requested.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.SaveSecrets" id="org.freedesktop.NetworkManager.SecretAgent.SaveSecrets">SaveSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Save given secrets to backing storage.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the entire connection
+                    (including secrets), for which the agent should save the
+                    secrets to backing storage.  This method will not be called
+                    when the agent itself is the process creating or updating
+                    a connection; in that case the agent is assumed to have
+                    already saved those secrets since it had them already.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which the agent should
+                    save secrets to backing storage.
+                </dd></dl></div></div><div class="method"><h3><a name="org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets" id="org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets">DeleteSecrets</a> (
+        a{sa{sv}}: connection, o: connection_path
+        ) &#8594;
+        nothing</h3><div class="docstring">
+                Delete secrets from backing storage.
+            </div><div><h4>Parameters</h4><dl><dt><code>connection</code> -
+      <code>a{sa{sv}}</code>
+      (<a xmlns="" href="#type-String_String_Variant_Map_Map">String_String_Variant_Map_Map</a>)
+    </dt><dd>
+                    Nested settings maps containing the connection properties
+                    (sans secrets), for which the agent should delete the
+                    secrets from backing storage.
+                </dd><dt><code>connection_path</code> -
+      <code>o</code></dt><dd>
+                    Object path of the connection for which the agent should
+                    delete secrets from backing storage.
+                </dd></dl></div></div><p>Interface has no signals.</p><p>Interface has no properties.</p><h2>Sets of flags:</h2><h3 xmlns=""><a name="type-NM_SECRET_AGENT_GET_SECRETS_FLAGS" id="type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a></h3>
+            Flags modifying the behavior of GetSecrets request.
+          <dl><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0</code></dt><dd>
+              No special behavior; by default no user interaction is allowed and
+              requests for secrets are fulfilled from persistent storage, or
+              if no secrets are available an error is returned.
+            </dd><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1</code></dt><dd>
+              Allows the request to interact with the user, possibly prompting
+              via UI for secrets if any are required, or if none are found in
+              persistent storage.
+            </dd><dt><code>NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2</code></dt><dd>
+              Explicitly prompt for new secrets from the user.  This flag
+              signals that NetworkManager thinks any existing secrets are
+              invalid or wrong.  This flag implies that interaction is allowed.
+            </dd></dl>
+
+
   <h1><a name="org.freedesktop.NetworkManager.VPN.Connection" id="org.freedesktop.NetworkManager.VPN.Connection"></a>org.freedesktop.NetworkManager.VPN.Connection</h1>
       Represents an active connection to a Virtual Private Network.
     <p>Interface has no methods.</p><h2>Signals:</h2><div class="signal"><h3><a name="org.freedesktop.NetworkManager.VPN.Connection.PropertiesChanged" id="org.freedesktop.NetworkManager.VPN.Connection.PropertiesChanged">PropertiesChanged</a> (
@@ -1379,7 +1502,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.BadArguments" id="org.freedesktop.NetworkManager.VPN.Error.BadArguments"></a>org.freedesktop.NetworkManager.VPN.Error.BadArguments</h2>Invalid arguments were passed with the request.  FIXME: too general.
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.LaunchFailed" id="org.freedesktop.NetworkManager.VPN.Error.LaunchFailed"></a>org.freedesktop.NetworkManager.VPN.Error.LaunchFailed</h2>A binary providing the service failed to launch.
   <h2><a name="org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid" id="org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid"></a>org.freedesktop.NetworkManager.VPN.Error.ConnectionInvalid</h2>The request could not be processed because the VPN connection settings were invalid.
-<h1>Index</h1><h2>Index of interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul><h2>Index of types</h2><ul><li><code><a href="#type-NM_802_11_AP_FLAGS">NM_802_11_AP_FLAGS</a></code>
+<h1>Index</h1><h2>Index of interfaces</h2><ul><li><code><a href="#org.freedesktop.NetworkManager">org.freedesktop.NetworkManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AccessPoint">org.freedesktop.NetworkManager.AccessPoint</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device">org.freedesktop.NetworkManager.Device</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wired">org.freedesktop.NetworkManager.Device.Wired</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Wireless">org.freedesktop.NetworkManager.Device.Wireless</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Modem">org.freedesktop.NetworkManager.Device.Modem</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.Bluetooth">org.freedesktop.NetworkManager.Device.Bluetooth</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.OlpcMesh">org.freedesktop.NetworkManager.Device.OlpcMesh</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Device.WiMax">org.freedesktop.NetworkManager.Device.WiMax</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.WiMax.Nsp">org.freedesktop.NetworkManager.WiMax.Nsp</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP4Config">org.freedesktop.NetworkManager.IP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.IP6Config">org.freedesktop.NetworkManager.IP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP4Config">org.freedesktop.NetworkManager.DHCP4Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.DHCP6Config">org.freedesktop.NetworkManager.DHCP6Config</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings">org.freedesktop.NetworkManager.Settings</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Settings.Connection">org.freedesktop.NetworkManager.Settings.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.Connection.Active">org.freedesktop.NetworkManager.Connection.Active</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.AgentManager">org.freedesktop.NetworkManager.AgentManager</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.SecretAgent">org.freedesktop.NetworkManager.SecretAgent</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Connection">org.freedesktop.NetworkManager.VPN.Connection</a></code></li><li><code><a href="#org.freedesktop.NetworkManager.VPN.Plugin">org.freedesktop.NetworkManager.VPN.Plugin</a></code></li></ul><h2>Index of types</h2><ul><li><code><a href="#type-NM_802_11_AP_FLAGS">NM_802_11_AP_FLAGS</a></code>
     - u</li><li><code><a href="#type-NM_802_11_AP_SEC">NM_802_11_AP_SEC</a></code>
     - u</li><li><code><a href="#type-NM_802_11_DEVICE_CAP">NM_802_11_DEVICE_CAP</a></code>
     - u</li><li><code><a href="#type-NM_802_11_MODE">NM_802_11_MODE</a></code>
@@ -1390,6 +1513,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
     - u</li><li><code><a href="#type-NM_DEVICE_STATE">NM_DEVICE_STATE</a></code>
     - u</li><li><code><a href="#type-NM_DEVICE_STATE_REASON">NM_DEVICE_STATE_REASON</a></code>
     - u</li><li><code><a href="#type-NM_DEVICE_TYPE">NM_DEVICE_TYPE</a></code>
+    - u</li><li><code><a href="#type-NM_SECRET_AGENT_GET_SECRETS_FLAGS">NM_SECRET_AGENT_GET_SECRETS_FLAGS</a></code>
     - u</li><li><code><a href="#type-NM_STATE">NM_STATE</a></code>
     - u</li><li><code><a href="#type-NM_VPN_CONNECTION_STATE">NM_VPN_CONNECTION_STATE</a></code>
     - u</li><li><code><a href="#type-NM_VPN_CONNECTION_STATE_REASON">NM_VPN_CONNECTION_STATE_REASON</a></code>
diff --git a/docs/api/version.xml b/docs/api/version.xml
index ac39a106..1d85bbe4 100644
--- a/docs/api/version.xml
+++ b/docs/api/version.xml
@@ -1 +1 @@
-0.9.0
+0.9.1.90
diff --git a/docs/libnm-glib/Makefile.in b/docs/libnm-glib/Makefile.in
index 775d33be..2ce5e8ab 100644
--- a/docs/libnm-glib/Makefile.in
+++ b/docs/libnm-glib/Makefile.in
@@ -159,6 +159,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/docs/libnm-glib/html/ch02.html b/docs/libnm-glib/html/ch02.html
index 4aa9ceee..aad96457 100644
--- a/docs/libnm-glib/html/ch02.html
+++ b/docs/libnm-glib/html/ch02.html
@@ -21,7 +21,7 @@
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="id446675"></a>libnm-glib API Reference</h2></div></div></div>
+<a name="id518696"></a>libnm-glib API Reference</h2></div></div></div>
 <div class="toc"><dl>
 <dt>
 <span class="refentrytitle"><a href="NMClient.html">NMClient</a></span><span class="refpurpose"></span>
diff --git a/docs/libnm-glib/html/index.html b/docs/libnm-glib/html/index.html
index 10f59ff8..c3596613 100644
--- a/docs/libnm-glib/html/index.html
+++ b/docs/libnm-glib/html/index.html
@@ -29,7 +29,7 @@
     </p></div>
 <div><p class="copyright">Copyright © 2011 The NetworkManager Authors</p></div>
 <div><div class="legalnotice">
-<a name="id417078"></a><p>
+<a name="id489099"></a><p>
 	Permission is granted to copy, distribute and/or modify this
 	document under the terms of the <em class="citetitle">GNU Free
 	Documentation License</em>, Version 1.1 or any later
diff --git a/docs/libnm-util/Makefile.in b/docs/libnm-util/Makefile.in
index 0b90a06e..980f5287 100644
--- a/docs/libnm-util/Makefile.in
+++ b/docs/libnm-util/Makefile.in
@@ -159,6 +159,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/docs/libnm-util/html/NMConnection.html b/docs/libnm-util/html/NMConnection.html
index c700c0d9..5fc9cb01 100644
--- a/docs/libnm-util/html/NMConnection.html
+++ b/docs/libnm-util/html/NMConnection.html
@@ -82,6 +82,10 @@ enum                <a class="link" href="NMConnection.html#NMConnectionError">N
 const <span class="returnvalue">char</span> *        <a class="link" href="NMConnection.html#nm-connection-need-secrets" title="nm_connection_need_secrets ()">nm_connection_need_secrets</a>          (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>,
                                                          <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> **hints</code></em>);
 <span class="returnvalue">void</span>                <a class="link" href="NMConnection.html#nm-connection-clear-secrets" title="nm_connection_clear_secrets ()">nm_connection_clear_secrets</a>         (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>);
+<span class="returnvalue">void</span>                <a class="link" href="NMConnection.html#nm-connection-clear-secrets-with-flags" title="nm_connection_clear_secrets_with_flags ()">nm_connection_clear_secrets_with_flags</a>
+                                                        (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()"><span class="type">NMSettingClearSecretsWithFlagsFn</span></a> func</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);
 <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>            <a class="link" href="NMConnection.html#nm-connection-update-secrets" title="nm_connection_update_secrets ()">nm_connection_update_secrets</a>        (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>,
                                                          <em class="parameter"><code>const <span class="type">char</span> *setting_name</code></em>,
                                                          <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Hash-Tables.html#GHashTable"><span class="type">GHashTable</span></a> *secrets</code></em>,
@@ -153,6 +157,7 @@ const <span class="returnvalue">char</span> *        <a class="link" href="NMCon
 <div class="refsect1">
 <a name="NMConnection.signals"></a><h2>Signals</h2>
 <pre class="synopsis">
+  "<a class="link" href="NMConnection.html#NMConnection-secrets-cleared" title='The "secrets-cleared" signal'>secrets-cleared</a>"                                : <a href="http://library.gnome.org/devel/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS"><code class="literal">Run First</code></a>
   "<a class="link" href="NMConnection.html#NMConnection-secrets-updated" title='The "secrets-updated" signal'>secrets-updated</a>"                                : <a href="http://library.gnome.org/devel/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS"><code class="literal">Run First</code></a>
 </pre>
 </div>
@@ -700,6 +705,37 @@ keeping secret data in memory when not needed.
 </div>
 <hr>
 <div class="refsect2">
+<a name="nm-connection-clear-secrets-with-flags"></a><h3>nm_connection_clear_secrets_with_flags ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>                nm_connection_clear_secrets_with_flags
+                                                        (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()"><span class="type">NMSettingClearSecretsWithFlagsFn</span></a> func</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>
+Clears and frees secrets determined by <em class="parameter"><code>func</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>connection</code></em> :</span></p></td>
+<td>the <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>func</code></em> :</span></p></td>
+<td>function to be called to determine whether a specific secret should be
+cleared or not</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>user_data</code></em> :</span></p></td>
+<td>caller-supplied data passed to <em class="parameter"><code>func</code></em>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="nm-connection-update-secrets"></a><h3>nm_connection_update_secrets ()</h3>
 <pre class="programlisting"><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>            nm_connection_update_secrets        (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>,
                                                          <em class="parameter"><code>const <span class="type">char</span> *setting_name</code></em>,
@@ -1344,6 +1380,29 @@ of the D-Bus path of the connection as provided by a settings service.
 <div class="refsect1">
 <a name="NMConnection.signal-details"></a><h2>Signal Details</h2>
 <div class="refsect2">
+<a name="NMConnection-secrets-cleared"></a><h3>The <code class="literal">"secrets-cleared"</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>                user_function                      (<a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection,
+                                                        <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>      user_data)       : <a href="http://library.gnome.org/devel/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS"><code class="literal">Run First</code></a></pre>
+<p>
+The ::secrets-cleared signal is emitted when the secrets of a connection
+are cleared.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>connection</code></em> :</span></p></td>
+<td>the object on which the signal is emitted</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>user_data</code></em> :</span></p></td>
+<td>user data set when the signal handler was connected.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="NMConnection-secrets-updated"></a><h3>The <code class="literal">"secrets-updated"</code> signal</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>                user_function                      (<a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection,
                                                         <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="type">gchar</span></a>        *setting_name,
diff --git a/docs/libnm-util/html/NMSetting.html b/docs/libnm-util/html/NMSetting.html
index 0cc1fd03..f33f7e56 100644
--- a/docs/libnm-util/html/NMSetting.html
+++ b/docs/libnm-util/html/NMSetting.html
@@ -56,6 +56,10 @@ enum                <a class="link" href="NMSetting.html#NMSettingError">NMSetti
 enum                <a class="link" href="NMSetting.html#NMSettingSecretFlags" title="enum NMSettingSecretFlags">NMSettingSecretFlags</a>;
 enum                <a class="link" href="NMSetting.html#NMSettingCompareFlags" title="enum NMSettingCompareFlags">NMSettingCompareFlags</a>;
                     <a class="link" href="NMSetting.html#NMSetting-struct" title="NMSetting">NMSetting</a>;
+<a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>            (<a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()">*NMSettingClearSecretsWithFlagsFn</a>) (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
+                                                         <em class="parameter"><code>const <span class="type">char</span> *secret</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingSecretFlags" title="enum NMSettingSecretFlags"><span class="type">NMSettingSecretFlags</span></a> flags</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);
                     <a class="link" href="NMSetting.html#NMSettingClass" title="NMSettingClass">NMSettingClass</a>;
 <span class="returnvalue">void</span>                (<a class="link" href="NMSetting.html#NMSettingValueIterFn" title="NMSettingValueIterFn ()">*NMSettingValueIterFn</a>)             (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
                                                          <em class="parameter"><code>const <span class="type">char</span> *key</code></em>,
@@ -87,6 +91,9 @@ enum                <a class="link" href="NMSetting.html#NMSettingDiffResult" ti
                                                          <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);
 <span class="returnvalue">char</span> *              <a class="link" href="NMSetting.html#nm-setting-to-string" title="nm_setting_to_string ()">nm_setting_to_string</a>                (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>);
 <span class="returnvalue">void</span>                <a class="link" href="NMSetting.html#nm-setting-clear-secrets" title="nm_setting_clear_secrets ()">nm_setting_clear_secrets</a>            (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>);
+<span class="returnvalue">void</span>                <a class="link" href="NMSetting.html#nm-setting-clear-secrets-with-flags" title="nm_setting_clear_secrets_with_flags ()">nm_setting_clear_secrets_with_flags</a> (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()"><span class="type">NMSettingClearSecretsWithFlagsFn</span></a> func</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);
 <a href="http://library.gnome.org/devel/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *         <a class="link" href="NMSetting.html#nm-setting-need-secrets" title="nm_setting_need_secrets ()">nm_setting_need_secrets</a>             (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>);
 <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>            <a class="link" href="NMSetting.html#nm-setting-update-secrets" title="nm_setting_update_secrets ()">nm_setting_update_secrets</a>           (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
                                                          <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Hash-Tables.html#GHashTable"><span class="type">GHashTable</span></a> *secrets</code></em>,
@@ -380,6 +387,42 @@ It should only be accessed through the functions described below.
 </div>
 <hr>
 <div class="refsect2">
+<a name="NMSettingClearSecretsWithFlagsFn"></a><h3>NMSettingClearSecretsWithFlagsFn ()</h3>
+<pre class="programlisting"><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>            (*NMSettingClearSecretsWithFlagsFn) (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
+                                                         <em class="parameter"><code>const <span class="type">char</span> *secret</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingSecretFlags" title="enum NMSettingSecretFlags"><span class="type">NMSettingSecretFlags</span></a> flags</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>setting</code></em> :</span></p></td>
+<td>The setting for which secrets are being iterated</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>secret</code></em> :</span></p></td>
+<td>The secret's name</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>flags</code></em> :</span></p></td>
+<td>The secret's flags, eg <a class="link" href="NMSetting.html#NM-SETTING-SECRET-FLAG-AGENT-OWNED:CAPS"><code class="literal">NM_SETTING_SECRET_FLAG_AGENT_OWNED</code></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>user_data</code></em> :</span></p></td>
+<td>User data passed to <a class="link" href="NMConnection.html#nm-connection-clear-secrets-with-flags" title="nm_connection_clear_secrets_with_flags ()"><code class="function">nm_connection_clear_secrets_with_flags()</code></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<a href="http://library.gnome.org/devel/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> to clear the secret, <a href="http://library.gnome.org/devel/glib/unstable/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> to not clear the secret</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="NMSettingClass"></a><h3>NMSettingClass</h3>
 <pre class="programlisting">typedef struct {
 	GObjectClass parent;
@@ -414,10 +457,14 @@ It should only be accessed through the functions described below.
 	                                  const GParamSpec *prop_spec,
 	                                  NMSettingCompareFlags flags);
 
+	void        (*clear_secrets_with_flags) (NMSetting *setting,
+	                                         GParamSpec *pspec,
+	                                         NMSettingClearSecretsWithFlagsFn func,
+	                                         gpointer user_data);
+
 	/* Padding for future expansion */
 	void (*_reserved1) (void);
 	void (*_reserved2) (void);
-	void (*_reserved3) (void);
 } NMSettingClass;
 </pre>
 <p>
@@ -851,6 +898,36 @@ leakage of information.
 </div>
 <hr>
 <div class="refsect2">
+<a name="nm-setting-clear-secrets-with-flags"></a><h3>nm_setting_clear_secrets_with_flags ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>                nm_setting_clear_secrets_with_flags (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>,
+                                                         <em class="parameter"><code><a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()"><span class="type">NMSettingClearSecretsWithFlagsFn</span></a> func</code></em>,
+                                                         <em class="parameter"><code><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>
+Clears and frees secrets determined by <em class="parameter"><code>func</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>setting</code></em> :</span></p></td>
+<td>the <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>func</code></em> :</span></p></td>
+<td>function to be called to determine whether a specific secret should be
+cleared or not</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>user_data</code></em> :</span></p></td>
+<td>caller-supplied data passed to <em class="parameter"><code>func</code></em>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="nm-setting-need-secrets"></a><h3>nm_setting_need_secrets ()</h3>
 <pre class="programlisting"><a href="http://library.gnome.org/devel/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *         nm_setting_need_secrets             (<em class="parameter"><code><a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> *setting</code></em>);</pre>
 <p>
diff --git a/docs/libnm-util/html/api-index-full.html b/docs/libnm-util/html/api-index-full.html
index f47ea2c9..4a913a44 100644
--- a/docs/libnm-util/html/api-index-full.html
+++ b/docs/libnm-util/html/api-index-full.html
@@ -21,20 +21,10 @@
 <td><a accesskey="n" href="annotation-glossary.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
 </tr>
 <tr><td colspan="5" class="shortcuts">
-<a class="shortcut" href="#idx8">8</a>
-                      | 
-                   <a class="shortcut" href="#idxA">A</a>
-                      | 
-                   <a class="shortcut" href="#idxB">B</a>
-                      | 
-                   <a class="shortcut" href="#idxC">C</a>
-                      | 
-                   <a class="shortcut" href="#idxD">D</a>
+<a class="shortcut" href="#idxC">C</a>
                       | 
                    <a class="shortcut" href="#idxI">I</a>
                       | 
-                   <a class="shortcut" href="#idxM">M</a>
-                      | 
                    <a class="shortcut" href="#idxS">S</a>
                       | 
                    <a class="shortcut" href="#idxT">T</a>
@@ -49,36 +39,13 @@
 <div class="index">
 <div class="titlepage"><div><div><h2 class="title">
 <a name="api-index-full"></a>API Index</h2></div></div></div>
-<a name="idx"></a><a name="idx8"></a><h3 class="title">8</h3>
-<dt>
-NM80211ApFlags, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM80211ApSecurityFlags, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM80211Mode, enum in NetworkManager
-</dt>
-<dd></dd>
-<a name="idxA"></a><h3 class="title">A</h3>
-<dt>
-NMActiveConnectionState, enum in NetworkManager
-</dt>
-<dd></dd>
-<a name="idxB"></a><h3 class="title">B</h3>
-<dt>
-NMBluetoothCapabilities, enum in NetworkManager
-</dt>
-<dd></dd>
-<a name="idxC"></a><h3 class="title">C</h3>
+<a name="idx"></a><a name="idxC"></a><h3 class="title">C</h3>
 <dt>
-NM_CHECK_VERSION, macro in nm-version
+<a class="link" href="NMConnection.html#NMConnection-struct" title="NMConnection">NMConnection</a>, struct in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="NMConnection.html#NMConnection-struct" title="NMConnection">NMConnection</a>, struct in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
+<a class="link" href="NMConnection.html#NMConnection-secrets-cleared" title='The "secrets-cleared" signal'>NMConnection::secrets-cleared</a>, object signal in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
 </dt>
 <dd></dd>
 <dt>
@@ -106,6 +73,10 @@ NM_CHECK_VERSION, macro in nm-version
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="NMConnection.html#nm-connection-clear-secrets-with-flags" title="nm_connection_clear_secrets_with_flags ()">nm_connection_clear_secrets_with_flags</a>, function in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="NMConnection.html#nm-connection-compare" title="nm_connection_compare ()">nm_connection_compare</a>, function in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
 </dt>
 <dd></dd>
@@ -269,275 +240,6 @@ NM_CHECK_VERSION, macro in nm-version
 <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()">nm_connection_verify</a>, function in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
 </dt>
 <dd></dd>
-<a name="idxD"></a><h3 class="title">D</h3>
-<dt>
-NM_DBUS_IFACE_SETTINGS, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_IFACE_SETTINGS_CONNECTION, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_ACCESS_POINT, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_ACTIVE_CONNECTION, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_AGENT_MANAGER, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE_MODEM, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE_WIMAX, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE_WIRED, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DEVICE_WIRELESS, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DHCP4_CONFIG, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_DHCP6_CONFIG, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_IP4_CONFIG, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_IP6_CONFIG, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_SECRET_AGENT, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_VPN, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_VPN_CONNECTION, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INTERFACE_WIMAX_NSP, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_INVALID_VPN_CONNECTION, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_NO_ACTIVE_VPN_CONNECTION, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_NO_VPN_CONNECTIONS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_ACCESS_POINT, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_AGENT_MANAGER, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_SECRET_AGENT, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_SETTINGS, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_SETTINGS_CONNECTION, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_VPN, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_VPN_CONNECTION, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_PATH_WIMAX_NSP, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_SERVICE, macro in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_STRING, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_ARRAY_OF_UINT, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_IP6_ADDRESS, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_IP6_ROUTE, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_LIST_OF_STRING, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_MAP_OF_STRING, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-DBUS_TYPE_G_MAP_OF_VARIANT, macro in nm-dbus-glib-types
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_ALREADY_STARTED, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_ALREADY_STOPPED, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_BAD_ARGUMENTS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_CONNECT_FAILED, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_IP4_CONFIG, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_LOGIN_BANNER, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_LOGIN_FAILED, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_STATE_CHANGE, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_STARTING_IN_PROGRESS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_STOPPING_IN_PROGRESS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_DBUS_VPN_WRONG_STATE, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NMDeviceCapabilities, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NMDeviceModemCapabilities, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NMDeviceState, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NMDeviceStateReason, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NMDeviceType, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NMDeviceWifiCapabilities, enum in NetworkManager
-</dt>
-<dd></dd>
 <a name="idxI"></a><h3 class="title">I</h3>
 <dt>
 <a class="link" href="NMSettingIP4Config.html#NMIP4Address">NMIP4Address</a>, typedef in <a class="link" href="NMSettingIP4Config.html" title="NMSettingIP4Config">NMSettingIP4Config</a>
@@ -763,19 +465,6 @@ NMDeviceWifiCapabilities, enum in NetworkManager
 <a class="link" href="NMSettingIP6Config.html#nm-ip6-route-unref" title="nm_ip6_route_unref ()">nm_ip6_route_unref</a>, function in <a class="link" href="NMSettingIP6Config.html" title="NMSettingIP6Config">NMSettingIP6Config</a>
 </dt>
 <dd></dd>
-<a name="idxM"></a><h3 class="title">M</h3>
-<dt>
-NM_MAJOR_VERSION, macro in nm-version
-</dt>
-<dd></dd>
-<dt>
-NM_MICRO_VERSION, macro in nm-version
-</dt>
-<dd></dd>
-<dt>
-NM_MINOR_VERSION, macro in nm-version
-</dt>
-<dd></dd>
 <a name="idxS"></a><h3 class="title">S</h3>
 <dt>
 <a class="link" href="NMSetting.html#NMSetting-struct" title="NMSetting">NMSetting</a>, struct in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a>
@@ -966,6 +655,10 @@ NM_MINOR_VERSION, macro in nm-version
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="NMSetting.html#NMSettingClearSecretsWithFlagsFn" title="NMSettingClearSecretsWithFlagsFn ()">NMSettingClearSecretsWithFlagsFn</a>, user_function in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="NMSetting.html#NMSettingCompareFlags" title="enum NMSettingCompareFlags">NMSettingCompareFlags</a>, enum in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a>
 </dt>
 <dd></dd>
@@ -2098,6 +1791,10 @@ NM_MINOR_VERSION, macro in nm-version
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="NMSetting.html#nm-setting-clear-secrets-with-flags" title="nm_setting_clear_secrets_with_flags ()">nm_setting_clear_secrets_with_flags</a>, function in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="NMSetting.html#nm-setting-compare" title="nm_setting_compare ()">nm_setting_compare</a>, function in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a>
 </dt>
 <dd></dd>
@@ -3661,14 +3358,6 @@ NM_SETTING_SECRET_FLAGS_ALL, macro in nm-setting-private
 <a class="link" href="NMSettingWireless.html#NM-SETTING-WIRELESS-TX-POWER:CAPS" title="NM_SETTING_WIRELESS_TX_POWER">NM_SETTING_WIRELESS_TX_POWER</a>, macro in <a class="link" href="NMSettingWireless.html" title="NMSettingWireless">NMSettingWireless</a>
 </dt>
 <dd></dd>
-<dt>
-NMState, enum in NetworkManager
-</dt>
-<dd></dd>
-<dt>
-NM_STATE_CONNECTED, macro in NetworkManager
-</dt>
-<dd></dd>
 <a name="idxT"></a><h3 class="title">T</h3>
 <dt>
 <a class="link" href="NMConnection.html#NM-TYPE-CONNECTION-ERROR:CAPS" title="NM_TYPE_CONNECTION_ERROR">NM_TYPE_CONNECTION_ERROR</a>, macro in <a class="link" href="NMConnection.html" title="NMConnection">NMConnection</a>
@@ -3865,93 +3554,9 @@ NM_STATE_CONNECTED, macro in NetworkManager
 <dd></dd>
 <a name="idxV"></a><h3 class="title">V</h3>
 <dt>
-NMVPNConnectionState, enum in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NMVPNConnectionStateReason, enum in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
 <a class="link" href="NMSettingVPN.html#NMVPNIterFunc" title="NMVPNIterFunc ()">NMVPNIterFunc</a>, user_function in <a class="link" href="NMSettingVPN.html" title="NMSettingVPN">NMSettingVPN</a>
 </dt>
 <dd></dd>
-<dt>
-NMVPNPluginFailure, enum in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NMVPNServiceState, enum in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_DBUS_PLUGIN_INTERFACE, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_DBUS_PLUGIN_PATH, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_BANNER, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_DNS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_MSS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_MTU, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_NBNS, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_PTP, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
-<dt>
-NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, macro in NetworkManagerVPN
-</dt>
-<dd></dd>
 <a name="idxW"></a><h3 class="title">W</h3>
 <dt>
 <a class="link" href="NMSettingWirelessSecurity.html#NMWepKeyType" title="enum NMWepKeyType">NMWepKeyType</a>, enum in <a class="link" href="NMSettingWirelessSecurity.html" title="NMSettingWirelessSecurity">NMSettingWirelessSecurity</a>
diff --git a/docs/libnm-util/html/ch01.html b/docs/libnm-util/html/ch01.html
index d97a8939..abd30410 100644
--- a/docs/libnm-util/html/ch01.html
+++ b/docs/libnm-util/html/ch01.html
@@ -21,7 +21,7 @@
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="id503033"></a>libnm-util API Reference</h2></div></div></div>
+<a name="id494534"></a>libnm-util API Reference</h2></div></div></div>
 <div class="toc"><dl>
 <dt>
 <span class="refentrytitle"><a href="NMConnection.html">NMConnection</a></span><span class="refpurpose"> — Describes a connection to specific network or provider</span>
diff --git a/docs/libnm-util/html/index.sgml b/docs/libnm-util/html/index.sgml
index eda2a542..84b45556 100644
--- a/docs/libnm-util/html/index.sgml
+++ b/docs/libnm-util/html/index.sgml
@@ -33,6 +33,7 @@
 <ANCHOR id="nm-connection-verify" href="libnm-util/NMConnection.html#nm-connection-verify">
 <ANCHOR id="nm-connection-need-secrets" href="libnm-util/NMConnection.html#nm-connection-need-secrets">
 <ANCHOR id="nm-connection-clear-secrets" href="libnm-util/NMConnection.html#nm-connection-clear-secrets">
+<ANCHOR id="nm-connection-clear-secrets-with-flags" href="libnm-util/NMConnection.html#nm-connection-clear-secrets-with-flags">
 <ANCHOR id="nm-connection-update-secrets" href="libnm-util/NMConnection.html#nm-connection-update-secrets">
 <ANCHOR id="nm-connection-set-path" href="libnm-util/NMConnection.html#nm-connection-set-path">
 <ANCHOR id="nm-connection-get-path" href="libnm-util/NMConnection.html#nm-connection-get-path">
@@ -61,6 +62,7 @@
 <ANCHOR id="NMConnection.property-details" href="libnm-util/NMConnection.html#NMConnection.property-details">
 <ANCHOR id="NMConnection--path" href="libnm-util/NMConnection.html#NMConnection--path">
 <ANCHOR id="NMConnection.signal-details" href="libnm-util/NMConnection.html#NMConnection.signal-details">
+<ANCHOR id="NMConnection-secrets-cleared" href="libnm-util/NMConnection.html#NMConnection-secrets-cleared">
 <ANCHOR id="NMConnection-secrets-updated" href="libnm-util/NMConnection.html#NMConnection-secrets-updated">
 <ANCHOR id="NMSetting" href="libnm-util/NMSetting.html">
 <ANCHOR id="NMSetting.synopsis" href="libnm-util/NMSetting.html#NMSetting.synopsis">
@@ -95,6 +97,7 @@
 <ANCHOR id="NM-SETTING-COMPARE-FLAG-IGNORE-AGENT-OWNED-SECRETS:CAPS" href="libnm-util/NMSetting.html#NM-SETTING-COMPARE-FLAG-IGNORE-AGENT-OWNED-SECRETS:CAPS">
 <ANCHOR id="NM-SETTING-COMPARE-FLAG-IGNORE-NOT-SAVED-SECRETS:CAPS" href="libnm-util/NMSetting.html#NM-SETTING-COMPARE-FLAG-IGNORE-NOT-SAVED-SECRETS:CAPS">
 <ANCHOR id="NMSetting-struct" href="libnm-util/NMSetting.html#NMSetting-struct">
+<ANCHOR id="NMSettingClearSecretsWithFlagsFn" href="libnm-util/NMSetting.html#NMSettingClearSecretsWithFlagsFn">
 <ANCHOR id="NMSettingClass" href="libnm-util/NMSetting.html#NMSettingClass">
 <ANCHOR id="NMSettingValueIterFn" href="libnm-util/NMSetting.html#NMSettingValueIterFn">
 <ANCHOR id="nm-setting-get-type" href="libnm-util/NMSetting.html#nm-setting-get-type">
@@ -116,6 +119,7 @@
 <ANCHOR id="nm-setting-enumerate-values" href="libnm-util/NMSetting.html#nm-setting-enumerate-values">
 <ANCHOR id="nm-setting-to-string" href="libnm-util/NMSetting.html#nm-setting-to-string">
 <ANCHOR id="nm-setting-clear-secrets" href="libnm-util/NMSetting.html#nm-setting-clear-secrets">
+<ANCHOR id="nm-setting-clear-secrets-with-flags" href="libnm-util/NMSetting.html#nm-setting-clear-secrets-with-flags">
 <ANCHOR id="nm-setting-need-secrets" href="libnm-util/NMSetting.html#nm-setting-need-secrets">
 <ANCHOR id="nm-setting-update-secrets" href="libnm-util/NMSetting.html#nm-setting-update-secrets">
 <ANCHOR id="nm-setting-get-secret-flags" href="libnm-util/NMSetting.html#nm-setting-get-secret-flags">
diff --git a/docs/libnm-util/html/libnm-util.devhelp b/docs/libnm-util/html/libnm-util.devhelp
index 21ba39f2..126736d9 100644
--- a/docs/libnm-util/html/libnm-util.devhelp
+++ b/docs/libnm-util/html/libnm-util.devhelp
@@ -50,6 +50,7 @@
     <function name="nm_connection_verify ()" link="NMConnection.html#nm-connection-verify"/>
     <function name="nm_connection_need_secrets ()" link="NMConnection.html#nm-connection-need-secrets"/>
     <function name="nm_connection_clear_secrets ()" link="NMConnection.html#nm-connection-clear-secrets"/>
+    <function name="nm_connection_clear_secrets_with_flags ()" link="NMConnection.html#nm-connection-clear-secrets-with-flags"/>
     <function name="nm_connection_update_secrets ()" link="NMConnection.html#nm-connection-update-secrets"/>
     <function name="nm_connection_set_path ()" link="NMConnection.html#nm-connection-set-path"/>
     <function name="nm_connection_get_path ()" link="NMConnection.html#nm-connection-get-path"/>
@@ -76,6 +77,7 @@
     <function name="nm_connection_get_setting_wireless ()" link="NMConnection.html#nm-connection-get-setting-wireless"/>
     <function name="nm_connection_get_setting_wireless_security ()" link="NMConnection.html#nm-connection-get-setting-wireless-security"/>
     <function name="The &quot;path&quot; property" link="NMConnection.html#NMConnection--path"/>
+    <function name="The &quot;secrets-cleared&quot; signal" link="NMConnection.html#NMConnection-secrets-cleared"/>
     <function name="The &quot;secrets-updated&quot; signal" link="NMConnection.html#NMConnection-secrets-updated"/>
     <function name="enum NMSettingError" link="NMSetting.html#NMSettingError"/>
     <function name="NM_TYPE_SETTING_ERROR" link="NMSetting.html#NM-TYPE-SETTING-ERROR:CAPS"/>
@@ -89,6 +91,7 @@
     <function name="enum NMSettingSecretFlags" link="NMSetting.html#NMSettingSecretFlags"/>
     <function name="enum NMSettingCompareFlags" link="NMSetting.html#NMSettingCompareFlags"/>
     <function name="NMSetting" link="NMSetting.html#NMSetting-struct"/>
+    <function name="NMSettingClearSecretsWithFlagsFn ()" link="NMSetting.html#NMSettingClearSecretsWithFlagsFn"/>
     <function name="NMSettingClass" link="NMSetting.html#NMSettingClass"/>
     <function name="NMSettingValueIterFn ()" link="NMSetting.html#NMSettingValueIterFn"/>
     <function name="nm_setting_get_type ()" link="NMSetting.html#nm-setting-get-type"/>
@@ -104,6 +107,7 @@
     <function name="nm_setting_enumerate_values ()" link="NMSetting.html#nm-setting-enumerate-values"/>
     <function name="nm_setting_to_string ()" link="NMSetting.html#nm-setting-to-string"/>
     <function name="nm_setting_clear_secrets ()" link="NMSetting.html#nm-setting-clear-secrets"/>
+    <function name="nm_setting_clear_secrets_with_flags ()" link="NMSetting.html#nm-setting-clear-secrets-with-flags"/>
     <function name="nm_setting_need_secrets ()" link="NMSetting.html#nm-setting-need-secrets"/>
     <function name="nm_setting_update_secrets ()" link="NMSetting.html#nm-setting-update-secrets"/>
     <function name="nm_setting_get_secret_flags ()" link="NMSetting.html#nm-setting-get-secret-flags"/>
diff --git a/docs/libnm-util/html/libnm-util.devhelp2 b/docs/libnm-util/html/libnm-util.devhelp2
index a6544ddd..571a921a 100644
--- a/docs/libnm-util/html/libnm-util.devhelp2
+++ b/docs/libnm-util/html/libnm-util.devhelp2
@@ -50,6 +50,7 @@
     <keyword type="function" name="nm_connection_verify ()" link="NMConnection.html#nm-connection-verify"/>
     <keyword type="function" name="nm_connection_need_secrets ()" link="NMConnection.html#nm-connection-need-secrets"/>
     <keyword type="function" name="nm_connection_clear_secrets ()" link="NMConnection.html#nm-connection-clear-secrets"/>
+    <keyword type="function" name="nm_connection_clear_secrets_with_flags ()" link="NMConnection.html#nm-connection-clear-secrets-with-flags"/>
     <keyword type="function" name="nm_connection_update_secrets ()" link="NMConnection.html#nm-connection-update-secrets"/>
     <keyword type="function" name="nm_connection_set_path ()" link="NMConnection.html#nm-connection-set-path"/>
     <keyword type="function" name="nm_connection_get_path ()" link="NMConnection.html#nm-connection-get-path"/>
@@ -76,6 +77,7 @@
     <keyword type="function" name="nm_connection_get_setting_wireless ()" link="NMConnection.html#nm-connection-get-setting-wireless"/>
     <keyword type="function" name="nm_connection_get_setting_wireless_security ()" link="NMConnection.html#nm-connection-get-setting-wireless-security"/>
     <keyword type="property" name="The &quot;path&quot; property" link="NMConnection.html#NMConnection--path"/>
+    <keyword type="signal" name="The &quot;secrets-cleared&quot; signal" link="NMConnection.html#NMConnection-secrets-cleared"/>
     <keyword type="signal" name="The &quot;secrets-updated&quot; signal" link="NMConnection.html#NMConnection-secrets-updated"/>
     <keyword type="enum" name="enum NMSettingError" link="NMSetting.html#NMSettingError"/>
     <keyword type="macro" name="NM_TYPE_SETTING_ERROR" link="NMSetting.html#NM-TYPE-SETTING-ERROR:CAPS"/>
@@ -89,6 +91,7 @@
     <keyword type="enum" name="enum NMSettingSecretFlags" link="NMSetting.html#NMSettingSecretFlags"/>
     <keyword type="enum" name="enum NMSettingCompareFlags" link="NMSetting.html#NMSettingCompareFlags"/>
     <keyword type="struct" name="NMSetting" link="NMSetting.html#NMSetting-struct"/>
+    <keyword type="function" name="NMSettingClearSecretsWithFlagsFn ()" link="NMSetting.html#NMSettingClearSecretsWithFlagsFn"/>
     <keyword type="struct" name="NMSettingClass" link="NMSetting.html#NMSettingClass"/>
     <keyword type="function" name="NMSettingValueIterFn ()" link="NMSetting.html#NMSettingValueIterFn"/>
     <keyword type="function" name="nm_setting_get_type ()" link="NMSetting.html#nm-setting-get-type"/>
@@ -104,6 +107,7 @@
     <keyword type="function" name="nm_setting_enumerate_values ()" link="NMSetting.html#nm-setting-enumerate-values"/>
     <keyword type="function" name="nm_setting_to_string ()" link="NMSetting.html#nm-setting-to-string"/>
     <keyword type="function" name="nm_setting_clear_secrets ()" link="NMSetting.html#nm-setting-clear-secrets"/>
+    <keyword type="function" name="nm_setting_clear_secrets_with_flags ()" link="NMSetting.html#nm-setting-clear-secrets-with-flags"/>
     <keyword type="function" name="nm_setting_need_secrets ()" link="NMSetting.html#nm-setting-need-secrets"/>
     <keyword type="function" name="nm_setting_update_secrets ()" link="NMSetting.html#nm-setting-update-secrets"/>
     <keyword type="function" name="nm_setting_get_secret_flags ()" link="NMSetting.html#nm-setting-get-secret-flags"/>
diff --git a/docs/libnm-util/libnm-util-sections.txt b/docs/libnm-util/libnm-util-sections.txt
index 06bd0d32..17fa48a6 100644
--- a/docs/libnm-util/libnm-util-sections.txt
+++ b/docs/libnm-util/libnm-util-sections.txt
@@ -657,6 +657,7 @@ NM_SETTING_NAME
 NMSettingSecretFlags
 NMSettingCompareFlags
 NMSetting
+NMSettingClearSecretsWithFlagsFn
 NMSettingClass
 NMSettingValueIterFn
 nm_setting_get_type
@@ -672,6 +673,7 @@ nm_setting_diff
 nm_setting_enumerate_values
 nm_setting_to_string
 nm_setting_clear_secrets
+nm_setting_clear_secrets_with_flags
 nm_setting_need_secrets
 nm_setting_update_secrets
 nm_setting_get_secret_flags
@@ -769,6 +771,7 @@ nm_connection_diff
 nm_connection_verify
 nm_connection_need_secrets
 nm_connection_clear_secrets
+nm_connection_clear_secrets_with_flags
 nm_connection_update_secrets
 nm_connection_set_path
 nm_connection_get_path
diff --git a/examples/C/Makefile.in b/examples/C/Makefile.in
index ea5932e6..dff05ce7 100644
--- a/examples/C/Makefile.in
+++ b/examples/C/Makefile.in
@@ -193,6 +193,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/examples/C/glib/Makefile.in b/examples/C/glib/Makefile.in
index 1d637510..c9e97d0d 100644
--- a/examples/C/glib/Makefile.in
+++ b/examples/C/glib/Makefile.in
@@ -239,6 +239,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/examples/C/qt/Makefile.in b/examples/C/qt/Makefile.in
index a07fe015..6ec14068 100644
--- a/examples/C/qt/Makefile.in
+++ b/examples/C/qt/Makefile.in
@@ -196,6 +196,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/examples/Makefile.in b/examples/Makefile.in
index a84d601c..c7bfaf9c 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -192,6 +192,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/examples/python/Makefile.am b/examples/python/Makefile.am
index 7fa376ef..59e16088 100644
--- a/examples/python/Makefile.am
+++ b/examples/python/Makefile.am
@@ -6,6 +6,5 @@ EXTRA_DIST = \
 	list-connections.py \
 	show-bssids.py \
 	disconnect-device.py \
-	get-active-connections.py
-
-
+	get-active-connections.py \
+	list-devices.py
diff --git a/examples/python/Makefile.in b/examples/python/Makefile.in
index 983f843d..b36fb6f6 100644
--- a/examples/python/Makefile.in
+++ b/examples/python/Makefile.in
@@ -152,6 +152,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -461,7 +467,8 @@ uninstall-am:
 	list-connections.py \
 	show-bssids.py \
 	disconnect-device.py \
-	get-active-connections.py
+	get-active-connections.py \
+	list-devices.py
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/include/Makefile.in b/include/Makefile.in
index fda755a2..1b73bafa 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -179,6 +179,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/include/nm-version.h b/include/nm-version.h
index 3d3adfba..b893219d 100644
--- a/include/nm-version.h
+++ b/include/nm-version.h
@@ -43,7 +43,7 @@
  * Evaluates to the micro version number of NetworkManager which this source
  * compiled against.
  */
-#define NM_MICRO_VERSION (0)
+#define NM_MICRO_VERSION (1)
 
 /**
  * NM_CHECK_VERSION:
diff --git a/initscript/Arch/Makefile.in b/initscript/Arch/Makefile.in
index 86adf2b2..9e14b5fa 100644
--- a/initscript/Arch/Makefile.in
+++ b/initscript/Arch/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/Debian/Makefile.in b/initscript/Debian/Makefile.in
index 8b3384b6..9a775c87 100644
--- a/initscript/Debian/Makefile.in
+++ b/initscript/Debian/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/Gentoo/Makefile.in b/initscript/Gentoo/Makefile.in
index 5a1514ed..d1dba66a 100644
--- a/initscript/Gentoo/Makefile.in
+++ b/initscript/Gentoo/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/Makefile.in b/initscript/Makefile.in
index 582c9dd5..1790ecc3 100644
--- a/initscript/Makefile.in
+++ b/initscript/Makefile.in
@@ -202,6 +202,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/Mandriva/Makefile.in b/initscript/Mandriva/Makefile.in
index d1006a13..0adc2ffe 100644
--- a/initscript/Mandriva/Makefile.in
+++ b/initscript/Mandriva/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/RedHat/Makefile.in b/initscript/RedHat/Makefile.in
index 4449798b..40547773 100644
--- a/initscript/RedHat/Makefile.in
+++ b/initscript/RedHat/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/SUSE/Makefile.in b/initscript/SUSE/Makefile.in
index 5621ccdb..a468e47d 100644
--- a/initscript/SUSE/Makefile.in
+++ b/initscript/SUSE/Makefile.in
@@ -153,6 +153,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/Slackware/Makefile.in b/initscript/Slackware/Makefile.in
index df3222ff..581b8108 100644
--- a/initscript/Slackware/Makefile.in
+++ b/initscript/Slackware/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/linexa/Makefile.in b/initscript/linexa/Makefile.in
index 0b6124e2..244c9f58 100644
--- a/initscript/linexa/Makefile.in
+++ b/initscript/linexa/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/initscript/paldo/Makefile.in b/initscript/paldo/Makefile.in
index d7550c6a..51ad0b66 100644
--- a/initscript/paldo/Makefile.in
+++ b/initscript/paldo/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/introspection/Makefile.in b/introspection/Makefile.in
index 95c3c47e..d8e9020f 100644
--- a/introspection/Makefile.in
+++ b/introspection/Makefile.in
@@ -153,6 +153,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/introspection/all.xml.in b/introspection/all.xml.in
index 4d2c2721..bcb8d045 100644
--- a/introspection/all.xml.in
+++ b/introspection/all.xml.in
@@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
 <xi:include href="nm-settings-connection.xml"/>
 <xi:include href="nm-active-connection.xml"/>
 <xi:include href="nm-agent-manager.xml"/>
+<xi:include href="nm-secret-agent.xml"/>
 <xi:include href="nm-vpn-connection.xml"/>
 <xi:include href="nm-vpn-plugin.xml"/>
 
diff --git a/libnm-glib/Makefile.in b/libnm-glib/Makefile.in
index 9728f7d9..4c8a9c34 100644
--- a/libnm-glib/Makefile.in
+++ b/libnm-glib/Makefile.in
@@ -348,6 +348,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in
index d4d5e6b5..58d95ea5 100644
--- a/libnm-glib/tests/Makefile.in
+++ b/libnm-glib/tests/Makefile.in
@@ -188,6 +188,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am
index 0a29e9c5..1529b4ad 100644
--- a/libnm-util/Makefile.am
+++ b/libnm-util/Makefile.am
@@ -69,7 +69,7 @@ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS)
 SYMBOL_VIS_FILE=$(srcdir)/libnm-util.ver
 
 libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
-	-version-info "2:0:0"
+	-version-info "3:0:1"
 
 if WITH_GNUTLS
 libnm_util_la_SOURCES += crypto_gnutls.c
diff --git a/libnm-util/Makefile.in b/libnm-util/Makefile.in
index d251ea8c..a67c544d 100644
--- a/libnm-util/Makefile.in
+++ b/libnm-util/Makefile.in
@@ -314,6 +314,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -492,7 +498,7 @@ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) \
 	$(am__append_3) $(am__append_6)
 SYMBOL_VIS_FILE = $(srcdir)/libnm-util.ver
 libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
-	-version-info "2:0:0"
+	-version-info "3:0:1"
 
 libnm_util_includedir = $(includedir)/NetworkManager
 
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index 6052c275..edf5d292 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -2,6 +2,7 @@
 global:
 	nm_connection_add_setting;
 	nm_connection_clear_secrets;
+	nm_connection_clear_secrets_with_flags;
 	nm_connection_compare;
 	nm_connection_create_setting;
 	nm_connection_diff;
@@ -174,6 +175,7 @@ global:
 	nm_setting_cdma_get_username;
 	nm_setting_cdma_new;
 	nm_setting_clear_secrets;
+	nm_setting_clear_secrets_with_flags;
 	nm_setting_compare;
 	nm_setting_connection_add_permission;
 	nm_setting_connection_error_get_type;
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 91fc3afa..d59c8b47 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -127,7 +127,7 @@ enum {
 
 enum {
 	SECRETS_UPDATED,
-
+	SECRETS_CLEARED,
 	LAST_SIGNAL
 };
 
@@ -950,12 +950,6 @@ nm_connection_need_secrets (NMConnection *connection,
 	return name;
 }
 
-static void
-clear_setting_secrets (gpointer key, gpointer data, gpointer user_data)
-{
-	nm_setting_clear_secrets (NM_SETTING (data));
-}
-
 /**
  * nm_connection_clear_secrets:
  * @connection: the #NMConnection
@@ -966,12 +960,42 @@ clear_setting_secrets (gpointer key, gpointer data, gpointer user_data)
 void
 nm_connection_clear_secrets (NMConnection *connection)
 {
-	NMConnectionPrivate *priv;
+	GHashTableIter iter;
+	NMSetting *setting;
 
 	g_return_if_fail (NM_IS_CONNECTION (connection));
 
-	priv = NM_CONNECTION_GET_PRIVATE (connection);
-	g_hash_table_foreach (priv->settings, clear_setting_secrets, NULL);
+	g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
+	while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
+		nm_setting_clear_secrets (setting);
+
+	g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
+}
+
+/**
+ * nm_connection_clear_secrets_with_flags:
+ * @connection: the #NMConnection
+ * @func: function to be called to determine whether a specific secret should be
+ *  cleared or not
+ * @user_data: caller-supplied data passed to @func
+ *
+ * Clears and frees secrets determined by @func.
+ **/
+void
+nm_connection_clear_secrets_with_flags (NMConnection *connection,
+                                        NMSettingClearSecretsWithFlagsFn func,
+                                        gpointer user_data)
+{
+	GHashTableIter iter;
+	NMSetting *setting;
+
+	g_return_if_fail (NM_IS_CONNECTION (connection));
+
+	g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
+	while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
+		nm_setting_clear_secrets_with_flags (setting, func, user_data);
+
+	g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
 }
 
 /**
@@ -1609,5 +1633,20 @@ nm_connection_class_init (NMConnectionClass *klass)
 					  g_cclosure_marshal_VOID__STRING,
 					  G_TYPE_NONE, 1,
 					  G_TYPE_STRING);
+
+	/**
+	* NMConnection::secrets-cleared:
+	* @connection: the object on which the signal is emitted
+	*
+	* The ::secrets-cleared signal is emitted when the secrets of a connection
+	* are cleared.
+	*/
+	signals[SECRETS_CLEARED] =
+		g_signal_new ("secrets-cleared",
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              0, NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
 }
 
diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h
index 3cd18747..3245f7e6 100644
--- a/libnm-util/nm-connection.h
+++ b/libnm-util/nm-connection.h
@@ -147,6 +147,10 @@ const char *  nm_connection_need_secrets  (NMConnection *connection,
 
 void          nm_connection_clear_secrets (NMConnection *connection);
 
+void          nm_connection_clear_secrets_with_flags (NMConnection *connection,
+                                                      NMSettingClearSecretsWithFlagsFn func,
+                                                      gpointer user_data);
+
 gboolean      nm_connection_update_secrets (NMConnection *connection,
                                             const char *setting_name,
                                             GHashTable *secrets,
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index 50091cb9..755c1a45 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -612,6 +612,30 @@ compare_property (NMSetting *setting,
 }
 
 static void
+clear_secrets_with_flags (NMSetting *setting,
+	                      GParamSpec *pspec,
+	                      NMSettingClearSecretsWithFlagsFn func,
+	                      gpointer user_data)
+{
+	NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
+	GHashTableIter iter;
+	const char *secret;
+
+	if (priv->secrets == NULL)
+		return;
+
+	/* Iterate through secrets hash and check each entry */
+	g_hash_table_iter_init (&iter, priv->secrets);
+	while (g_hash_table_iter_next (&iter, (gpointer) &secret, NULL)) {
+		NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		nm_setting_get_secret_flags (setting, secret, &flags, NULL);
+		if (func (setting, pspec->name, flags, user_data) == TRUE)
+			g_hash_table_iter_remove (&iter);
+	}
+}
+
+static void
 destroy_one_secret (gpointer data)
 {
 	char *secret = (char *) data;
@@ -733,6 +757,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
 	parent_class->set_secret_flags  = set_secret_flags;
 	parent_class->need_secrets      = need_secrets;
 	parent_class->compare_property  = compare_property;
+	parent_class->clear_secrets_with_flags = clear_secrets_with_flags;
 
 	/* Properties */
 	/**
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index 3573f888..7ec4278f 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -648,6 +648,60 @@ nm_setting_clear_secrets (NMSetting *setting)
 	g_free (property_specs);
 }
 
+static void
+clear_secrets_with_flags (NMSetting *setting,
+	                      GParamSpec *pspec,
+	                      NMSettingClearSecretsWithFlagsFn func,
+	                      gpointer user_data)
+{
+	GValue value = { 0 };
+	NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+	/* Clear the secret if the user function says to do so */
+	nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL);
+	if (func (setting, pspec->name, flags, user_data) == TRUE) {
+		g_value_init (&value, pspec->value_type);
+		g_param_value_set_default (pspec, &value);
+		g_object_set_property (G_OBJECT (setting), pspec->name, &value);
+		g_value_unset (&value);
+	}
+}
+
+/**
+ * nm_setting_clear_secrets_with_flags:
+ * @setting: the #NMSetting
+ * @func: function to be called to determine whether a specific secret should be
+ *  cleared or not
+ * @user_data: caller-supplied data passed to @func
+ *
+ * Clears and frees secrets determined by @func.
+ **/
+void
+nm_setting_clear_secrets_with_flags (NMSetting *setting,
+                                     NMSettingClearSecretsWithFlagsFn func,
+                                     gpointer user_data)
+{
+	GParamSpec **property_specs;
+	guint n_property_specs;
+	guint i;
+
+	g_return_if_fail (setting);
+	g_return_if_fail (NM_IS_SETTING (setting));
+	g_return_if_fail (func != NULL);
+
+	property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
+	for (i = 0; i < n_property_specs; i++) {
+		if (property_specs[i]->flags & NM_SETTING_PARAM_SECRET) {
+			NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting,
+			                                                          property_specs[i],
+			                                                          func,
+			                                                          user_data);
+		}
+	}
+
+	g_free (property_specs);
+}
+
 /**
  * nm_setting_need_secrets:
  * @setting: the #NMSetting
@@ -1029,6 +1083,7 @@ nm_setting_class_init (NMSettingClass *setting_class)
 	setting_class->get_secret_flags = get_secret_flags;
 	setting_class->set_secret_flags = set_secret_flags;
 	setting_class->compare_property = compare_property;
+	setting_class->clear_secrets_with_flags = clear_secrets_with_flags;
 
 	/* Properties */
 
diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h
index e21efd81..3edf2a1f 100644
--- a/libnm-util/nm-setting.h
+++ b/libnm-util/nm-setting.h
@@ -150,6 +150,21 @@ typedef struct {
 	GObject parent;
 } NMSetting;
 
+
+/**
+ * NMSettingClearSecretsWithFlagsFn:
+ * @setting: The setting for which secrets are being iterated
+ * @secret: The secret's name
+ * @flags: The secret's flags, eg %NM_SETTING_SECRET_FLAG_AGENT_OWNED
+ * @user_data: User data passed to nm_connection_clear_secrets_with_flags()
+ *
+ * Returns: %TRUE to clear the secret, %FALSE to not clear the secret
+ */
+typedef gboolean (*NMSettingClearSecretsWithFlagsFn) (NMSetting *setting,
+                                                      const char *secret,
+                                                      NMSettingSecretFlags flags,
+                                                      gpointer user_data);
+
 typedef struct {
 	GObjectClass parent;
 
@@ -183,10 +198,14 @@ typedef struct {
 	                                  const GParamSpec *prop_spec,
 	                                  NMSettingCompareFlags flags);
 
+	void        (*clear_secrets_with_flags) (NMSetting *setting,
+	                                         GParamSpec *pspec,
+	                                         NMSettingClearSecretsWithFlagsFn func,
+	                                         gpointer user_data);
+
 	/* Padding for future expansion */
 	void (*_reserved1) (void);
 	void (*_reserved2) (void);
-	void (*_reserved3) (void);
 } NMSettingClass;
 
 /**
@@ -269,6 +288,11 @@ char       *nm_setting_to_string      (NMSetting *setting);
 
 /* Secrets */
 void        nm_setting_clear_secrets  (NMSetting *setting);
+
+void        nm_setting_clear_secrets_with_flags (NMSetting *setting,
+                                                 NMSettingClearSecretsWithFlagsFn func,
+                                                 gpointer user_data);
+
 GPtrArray  *nm_setting_need_secrets   (NMSetting *setting);
 gboolean    nm_setting_update_secrets (NMSetting *setting,
                                        GHashTable *secrets,
diff --git a/libnm-util/tests/Makefile.in b/libnm-util/tests/Makefile.in
index c4919ffc..df8fec77 100644
--- a/libnm-util/tests/Makefile.in
+++ b/libnm-util/tests/Makefile.in
@@ -250,6 +250,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/libnm-util/tests/certs/Makefile.in b/libnm-util/tests/certs/Makefile.in
index 5149078b..14abf272 100644
--- a/libnm-util/tests/certs/Makefile.in
+++ b/libnm-util/tests/certs/Makefile.in
@@ -161,6 +161,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/man/Makefile.in b/man/Makefile.in
index ef05bde1..4214f7cc 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -185,6 +185,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/man/nmcli.1 b/man/nmcli.1
index 5afb802b..03ed664c 100644
--- a/man/nmcli.1
+++ b/man/nmcli.1
@@ -20,9 +20,9 @@
 .\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
 .\" USA.
 .\"
-.\" Copyright (C) 2010 Red Hat, Inc.
+.\" Copyright (C) 2010 - 2011 Red Hat, Inc.
 .\"
-.TH NMCLI "1" "22 September 2010"
+.TH NMCLI "1" "6 September 2011"
 
 .SH NAME
 nmcli \- command-line tool for controlling NetworkManager
@@ -201,7 +201,7 @@ Connections
 .br
 Get information about NetworkManager's connections.
 .TP
-.SS \fICOMMAND\fP := { list | status | up | down }
+.SS \fICOMMAND\fP := { list | status | up | down | delete }
 .sp
 .RS
 .TP
@@ -226,7 +226,7 @@ Print status of active connections.
 No simple reference.
 .fi
 .TP
-.B up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [\-\-nowait] [\-\-timeout <timeout>]
+.B up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [\-\-nowait] [\-\-timeout <timeout>]
 .br
 Activate a connection.  The connection is identified by its name using \fIid\fP
 or UUID using \fIuuid\fP.  For requiring particular device to activate
@@ -255,6 +255,18 @@ interface: org.freedesktop.NetworkManager
 method:    DeactivateConnection
 arguments: according to arguments
 .fi
+.TP
+.B delete id <id> | uuid <id>
+.br
+Delete a configured connection.  The connection to delete is specified with
+\fIid\fP (connection name) or \fIuuid\fP (connection UUID).
+.br
+.nf
+\fBReference to D-Bus:\fP
+interface: org.freedesktop.NetworkManager.Settings.Connection
+method:    Delete
+arguments: none
+.fi
 .RE
 
 .TP
@@ -303,9 +315,9 @@ method:    Disconnect
 arguments: none
 .fi
 .TP
-.B wifi [list [iface <iface>] [hwaddr <hwaddr>]]
+.B wifi [list [iface <iface>] [bssid <BSSID>]]
 .br
-List available WiFi access points.  \fIiface\fP and \fIhwaddr\fP options
+List available WiFi access points.  \fIiface\fP and \fIbssid\fP options
 can be used to get just APs for particular interface or specific AP,
 respectively.
 .br
@@ -329,7 +341,7 @@ or null.
 .RE
 Notes about localization:
 .br
-Be aware that \fInmcli\fP is localized and that's why the output depends on 
+Be aware that \fInmcli\fP is localized and that's why the output depends on
 your environment. It's important to realize that especially when you parse the
 output.
 .br
diff --git a/man/nmcli.1.in b/man/nmcli.1.in
index 5afb802b..03ed664c 100644
--- a/man/nmcli.1.in
+++ b/man/nmcli.1.in
@@ -20,9 +20,9 @@
 .\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
 .\" USA.
 .\"
-.\" Copyright (C) 2010 Red Hat, Inc.
+.\" Copyright (C) 2010 - 2011 Red Hat, Inc.
 .\"
-.TH NMCLI "1" "22 September 2010"
+.TH NMCLI "1" "6 September 2011"
 
 .SH NAME
 nmcli \- command-line tool for controlling NetworkManager
@@ -201,7 +201,7 @@ Connections
 .br
 Get information about NetworkManager's connections.
 .TP
-.SS \fICOMMAND\fP := { list | status | up | down }
+.SS \fICOMMAND\fP := { list | status | up | down | delete }
 .sp
 .RS
 .TP
@@ -226,7 +226,7 @@ Print status of active connections.
 No simple reference.
 .fi
 .TP
-.B up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [\-\-nowait] [\-\-timeout <timeout>]
+.B up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [\-\-nowait] [\-\-timeout <timeout>]
 .br
 Activate a connection.  The connection is identified by its name using \fIid\fP
 or UUID using \fIuuid\fP.  For requiring particular device to activate
@@ -255,6 +255,18 @@ interface: org.freedesktop.NetworkManager
 method:    DeactivateConnection
 arguments: according to arguments
 .fi
+.TP
+.B delete id <id> | uuid <id>
+.br
+Delete a configured connection.  The connection to delete is specified with
+\fIid\fP (connection name) or \fIuuid\fP (connection UUID).
+.br
+.nf
+\fBReference to D-Bus:\fP
+interface: org.freedesktop.NetworkManager.Settings.Connection
+method:    Delete
+arguments: none
+.fi
 .RE
 
 .TP
@@ -303,9 +315,9 @@ method:    Disconnect
 arguments: none
 .fi
 .TP
-.B wifi [list [iface <iface>] [hwaddr <hwaddr>]]
+.B wifi [list [iface <iface>] [bssid <BSSID>]]
 .br
-List available WiFi access points.  \fIiface\fP and \fIhwaddr\fP options
+List available WiFi access points.  \fIiface\fP and \fIbssid\fP options
 can be used to get just APs for particular interface or specific AP,
 respectively.
 .br
@@ -329,7 +341,7 @@ or null.
 .RE
 Notes about localization:
 .br
-Be aware that \fInmcli\fP is localized and that's why the output depends on 
+Be aware that \fInmcli\fP is localized and that's why the output depends on
 your environment. It's important to realize that especially when you parse the
 output.
 .br
diff --git a/marshallers/Makefile.in b/marshallers/Makefile.in
index 5e2e86db..70f1296a 100644
--- a/marshallers/Makefile.in
+++ b/marshallers/Makefile.in
@@ -183,6 +183,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/policy/Makefile.in b/policy/Makefile.in
index c63e1c5e..c50c6123 100644
--- a/policy/Makefile.in
+++ b/policy/Makefile.in
@@ -177,6 +177,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/Makefile.am b/src/Makefile.am
index 94e1a8c0..c8caefb0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -159,6 +159,10 @@ NetworkManager_SOURCES = \
 		nm-manager-auth.h \
 		nm-netlink-monitor.c \
 		nm-netlink-monitor.h \
+		nm-netlink-utils.c \
+		nm-netlink-utils.h \
+		nm-netlink-compat.h \
+		nm-netlink-compat.c \
 		nm-activation-request.c \
 		nm-activation-request.h \
 		nm-properties-changed-signal.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 5d9567ed..9bb66f55 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -116,6 +116,8 @@ am_NetworkManager_OBJECTS = NetworkManager-nm-call-store.$(OBJEXT) \
 	NetworkManager-nm-manager.$(OBJEXT) \
 	NetworkManager-nm-manager-auth.$(OBJEXT) \
 	NetworkManager-nm-netlink-monitor.$(OBJEXT) \
+	NetworkManager-nm-netlink-utils.$(OBJEXT) \
+	NetworkManager-nm-netlink-compat.$(OBJEXT) \
 	NetworkManager-nm-activation-request.$(OBJEXT) \
 	NetworkManager-nm-properties-changed-signal.$(OBJEXT) \
 	NetworkManager-wpa.$(OBJEXT) \
@@ -338,6 +340,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -582,6 +590,10 @@ NetworkManager_SOURCES = \
 		nm-manager-auth.h \
 		nm-netlink-monitor.c \
 		nm-netlink-monitor.h \
+		nm-netlink-utils.c \
+		nm-netlink-utils.h \
+		nm-netlink-compat.h \
+		nm-netlink-compat.c \
 		nm-activation-request.c \
 		nm-activation-request.h \
 		nm-properties-changed-signal.c \
@@ -847,7 +859,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-ip6-config.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-manager-auth.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-netlink-compat.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-netlink-monitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-netlink-utils.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy-hostname.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy-hosts.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy.Po@am__quote@
@@ -1341,6 +1355,38 @@ NetworkManager-nm-netlink-monitor.obj: nm-netlink-monitor.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-netlink-monitor.obj `if test -f 'nm-netlink-monitor.c'; then $(CYGPATH_W) 'nm-netlink-monitor.c'; else $(CYGPATH_W) '$(srcdir)/nm-netlink-monitor.c'; fi`
 
+NetworkManager-nm-netlink-utils.o: nm-netlink-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-netlink-utils.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-netlink-utils.Tpo -c -o NetworkManager-nm-netlink-utils.o `test -f 'nm-netlink-utils.c' || echo '$(srcdir)/'`nm-netlink-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-netlink-utils.Tpo $(DEPDIR)/NetworkManager-nm-netlink-utils.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nm-netlink-utils.c' object='NetworkManager-nm-netlink-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-netlink-utils.o `test -f 'nm-netlink-utils.c' || echo '$(srcdir)/'`nm-netlink-utils.c
+
+NetworkManager-nm-netlink-utils.obj: nm-netlink-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-netlink-utils.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-netlink-utils.Tpo -c -o NetworkManager-nm-netlink-utils.obj `if test -f 'nm-netlink-utils.c'; then $(CYGPATH_W) 'nm-netlink-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-netlink-utils.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-netlink-utils.Tpo $(DEPDIR)/NetworkManager-nm-netlink-utils.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nm-netlink-utils.c' object='NetworkManager-nm-netlink-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-netlink-utils.obj `if test -f 'nm-netlink-utils.c'; then $(CYGPATH_W) 'nm-netlink-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-netlink-utils.c'; fi`
+
+NetworkManager-nm-netlink-compat.o: nm-netlink-compat.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-netlink-compat.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-netlink-compat.Tpo -c -o NetworkManager-nm-netlink-compat.o `test -f 'nm-netlink-compat.c' || echo '$(srcdir)/'`nm-netlink-compat.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-netlink-compat.Tpo $(DEPDIR)/NetworkManager-nm-netlink-compat.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nm-netlink-compat.c' object='NetworkManager-nm-netlink-compat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-netlink-compat.o `test -f 'nm-netlink-compat.c' || echo '$(srcdir)/'`nm-netlink-compat.c
+
+NetworkManager-nm-netlink-compat.obj: nm-netlink-compat.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-netlink-compat.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-netlink-compat.Tpo -c -o NetworkManager-nm-netlink-compat.obj `if test -f 'nm-netlink-compat.c'; then $(CYGPATH_W) 'nm-netlink-compat.c'; else $(CYGPATH_W) '$(srcdir)/nm-netlink-compat.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-netlink-compat.Tpo $(DEPDIR)/NetworkManager-nm-netlink-compat.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='nm-netlink-compat.c' object='NetworkManager-nm-netlink-compat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-netlink-compat.obj `if test -f 'nm-netlink-compat.c'; then $(CYGPATH_W) 'nm-netlink-compat.c'; else $(CYGPATH_W) '$(srcdir)/nm-netlink-compat.c'; fi`
+
 NetworkManager-nm-activation-request.o: nm-activation-request.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-activation-request.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-activation-request.Tpo -c -o NetworkManager-nm-activation-request.o `test -f 'nm-activation-request.c' || echo '$(srcdir)/'`nm-activation-request.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-activation-request.Tpo $(DEPDIR)/NetworkManager-nm-activation-request.Po
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index f96f2aad..451de6d0 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <stdlib.h>
 
 #include "NetworkManagerUtils.h"
 #include "nm-utils.h"
@@ -43,9 +44,6 @@
 #include "nm-setting-wireless-security.h"
 #include "nm-manager-auth.h"
 
-#include <netlink/addr.h>
-#include <netinet/in.h>
-
 /*
  * nm_ethernet_address_is_valid
  *
diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in
index 2f489e75..6776e343 100644
--- a/src/backends/Makefile.in
+++ b/src/backends/Makefile.in
@@ -232,6 +232,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c
index 8f16066f..89b8a46d 100644
--- a/src/backends/NetworkManagerGeneric.c
+++ b/src/backends/NetworkManagerGeneric.c
@@ -34,7 +34,9 @@
 #include "nm-system.h"
 #include "NetworkManagerUtils.h"
 #include "nm-logging.h"
+#include "nm-netlink-compat.h"
 #include "nm-netlink-monitor.h"
+#include "nm-netlink-utils.h"
 
 /* Because of a bug in libnl, rtnl.h should be included before route.h */
 #include <netlink/route/rtnl.h>
@@ -50,15 +52,13 @@
  */
 void nm_generic_enable_loopback (void)
 {
-	struct nl_handle *	nlh = NULL;
+	struct nl_sock *	nlh = NULL;
 	struct rtnl_addr *	addr = NULL;
 	struct nl_addr *	nl_addr = NULL;
 	guint32			binaddr = 0;
 	int			iface_idx = -1;
 	int			err;
 
-	nm_system_device_set_up_down_with_iface ("lo", TRUE, NULL);
-
 	nlh = nm_netlink_get_default_handle ();
 	if (!nlh)
 		return;
@@ -67,6 +67,8 @@ void nm_generic_enable_loopback (void)
 	if (iface_idx < 0)
 		return;
 
+	nm_system_iface_set_up (iface_idx, TRUE, NULL);
+
 	addr = rtnl_addr_alloc ();
 	if (!addr)
 		return;
@@ -90,10 +92,10 @@ void nm_generic_enable_loopback (void)
 	rtnl_addr_set_scope (addr, RT_SCOPE_HOST);
 	rtnl_addr_set_label (addr, "lo");
 
-	if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) {
-		if (err != -EEXIST) {
-			nm_log_warn (LOGD_CORE, "error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
-		}
+	err = rtnl_addr_add (nlh, addr, 0);
+	if (err && (err != -NLE_EXIST)) {
+		nm_log_warn (LOGD_CORE, "error setting loopback address: (%d) %s",
+			         err, nl_geterror (err));
 	}
 out:
 	if (addr)
diff --git a/src/bluez-manager/Makefile.in b/src/bluez-manager/Makefile.in
index 1336b7ec..e141456a 100644
--- a/src/bluez-manager/Makefile.in
+++ b/src/bluez-manager/Makefile.in
@@ -189,6 +189,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in
index dd557056..990c9363 100644
--- a/src/dhcp-manager/Makefile.in
+++ b/src/dhcp-manager/Makefile.in
@@ -237,6 +237,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in
index 7e875055..5e3167bb 100644
--- a/src/dhcp-manager/tests/Makefile.in
+++ b/src/dhcp-manager/tests/Makefile.in
@@ -187,6 +187,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in
index aad1c562..acc700e1 100644
--- a/src/dns-manager/Makefile.in
+++ b/src/dns-manager/Makefile.in
@@ -190,6 +190,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/dns-manager/nm-dns-bind.c b/src/dns-manager/nm-dns-bind.c
index fc7af776..55fce030 100644
--- a/src/dns-manager/nm-dns-bind.c
+++ b/src/dns-manager/nm-dns-bind.c
@@ -297,7 +297,8 @@ update (NMDnsPlugin *plugin,
         const GSList *vpn_configs,
         const GSList *dev_configs,
         const GSList *other_configs,
-        const char *hostname)
+        const char *hostname,
+        const char *iface)
 {
 	NMDnsBind *self = NM_DNS_BIND (plugin);
 	NMDnsBindPrivate *priv = NM_DNS_BIND_GET_PRIVATE (self);
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c
index 9cc01978..27672088 100644
--- a/src/dns-manager/nm-dns-dnsmasq.c
+++ b/src/dns-manager/nm-dns-dnsmasq.c
@@ -133,23 +133,56 @@ add_ip4_config (GString *str, NMIP4Config *ip4, gboolean split)
 	return TRUE;
 }
 
-static gboolean
-ip6_addr_to_string (const struct in6_addr *addr, char *buf, size_t buflen)
+#define IP6_ADDR_BUFLEN (INET6_ADDRSTRLEN + 50)
+
+static char *
+ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
 {
-	memset (buf, 0, buflen);
+	char *buf, *p;
+
+	/* allocate enough space for the address + interface name */
+	buf = g_malloc0 (IP6_ADDR_BUFLEN + 1);
 
 	/* inet_ntop is probably supposed to do this for us, but it doesn't */
-	if (IN6_IS_ADDR_V4MAPPED (addr))
-		return !!inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, buflen);
+	if (IN6_IS_ADDR_V4MAPPED (addr)) {
+		if (!inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, IP6_ADDR_BUFLEN))
+			goto error;
+		return buf;
+	}
 
-	return !!inet_ntop (AF_INET6, addr, buf, buflen);
+	if (!inet_ntop (AF_INET6, addr, buf, IP6_ADDR_BUFLEN))
+		goto error;
+
+	/* In the case of addr being a link-local address, inet_ntop can either
+	 * return an address with scope identifier already in place (like
+	 * fe80::202:b3ff:fe8d:7aaf%wlan0) or it returns an address without
+	 * scope identifier at all (like fe80::202:b3ff:fe8d:7aaf)
+	 */
+	p = strchr (buf, '%');
+	if (p) {
+		/* If we got a scope identifier, we need to replace the '%'
+		 * with '@', since dnsmasq supports '%' in server= addresses
+		 * only since version 2.58 and up
+		 */
+		*p = '@';
+	} else if (IN6_IS_ADDR_LINKLOCAL (addr)) {
+		/* If we got no scope identifier at all append the interface name */
+		strncat (buf, "@", IP6_ADDR_BUFLEN - strlen (buf));
+		strncat (buf, iface, IP6_ADDR_BUFLEN - strlen (buf));
+	}
+
+	return buf;
+
+error:
+	g_free (buf);
+	return NULL;
 }
 
 static gboolean
-add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
+add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split, const char *iface)
 {
-	char buf[INET6_ADDRSTRLEN + 1];
 	const struct in6_addr *addr;
+	char *buf;
 	int n, i;
 	gboolean added = FALSE;
 
@@ -159,7 +192,8 @@ add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
 		 * the first nameserver here.
 		 */
 		addr = nm_ip6_config_get_nameserver (ip6, 0);
-		if (!ip6_addr_to_string (addr, &buf[0], sizeof (buf)))
+		buf = ip6_addr_to_string (addr, iface);
+		if (!buf)
 			return FALSE;
 
 		/* searches are preferred over domains */
@@ -181,6 +215,8 @@ add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
 				added = TRUE;
 			}
 		}
+
+		g_free (buf);
 	}
 
 	/* If no searches or domains, just add the namservers */
@@ -188,8 +224,11 @@ add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
 		n = nm_ip6_config_get_num_nameservers (ip6);
 		for (i = 0; i < n; i++) {
 			addr = nm_ip6_config_get_nameserver (ip6, i);
-			if (ip6_addr_to_string (addr, &buf[0], sizeof (buf)))
+			buf = ip6_addr_to_string (addr, iface);
+			if (buf) {
 				g_string_append_printf (str, "server=%s\n", buf);
+				g_free (buf);
+			}
 		}
 	}
 
@@ -201,7 +240,8 @@ update (NMDnsPlugin *plugin,
         const GSList *vpn_configs,
         const GSList *dev_configs,
         const GSList *other_configs,
-        const char *hostname)
+        const char *hostname,
+        const char *iface)
 {
 	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
 	GString *conf;
@@ -226,7 +266,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), TRUE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), TRUE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), TRUE, iface);
 	}
 
 	/* Now add interface configs without split DNS */
@@ -234,7 +274,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE, iface);
 	}
 
 	/* And any other random configs */
@@ -242,7 +282,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE, iface);
 	}
 
 	/* Write out the config file */
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 49cd74e5..0203f2bb 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -711,7 +711,8 @@ update_dns (NMDnsManager *self,
 		                           vpn_configs,
 		                           dev_configs,
 		                           other_configs,
-		                           priv->hostname)) {
+		                           priv->hostname,
+					   iface)) {
 			nm_log_warn (LOGD_DNS, "DNS: plugin %s update failed", plugin_name);
 
 			/* If the plugin failed to update, we shouldn't write out a local
diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c
index ae230ada..e997948e 100644
--- a/src/dns-manager/nm-dns-plugin.c
+++ b/src/dns-manager/nm-dns-plugin.c
@@ -55,7 +55,8 @@ nm_dns_plugin_update (NMDnsPlugin *self,
                       const GSList *vpn_configs,
                       const GSList *dev_configs,
                       const GSList *other_configs,
-                      const char *hostname)
+                      const char *hostname,
+                      const char *iface)
 {
 	g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE);
 
@@ -63,7 +64,8 @@ nm_dns_plugin_update (NMDnsPlugin *self,
 	                                               vpn_configs,
 	                                               dev_configs,
 	                                               other_configs,
-	                                               hostname);
+	                                               hostname,
+						       iface);
 }
 
 static gboolean
diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h
index d4298b86..37dd7336 100644
--- a/src/dns-manager/nm-dns-plugin.h
+++ b/src/dns-manager/nm-dns-plugin.h
@@ -53,7 +53,8 @@ typedef struct {
 	                    const GSList *vpn_configs,
 	                    const GSList *dev_configs,
 	                    const GSList *other_configs,
-	                    const char *hostname);
+	                    const char *hostname,
+	                    const char *iface);
 
 	/* Subclasses should override and return TRUE if they start a local
 	 * caching nameserver that listens on localhost and would block any
@@ -91,7 +92,8 @@ gboolean nm_dns_plugin_update (NMDnsPlugin *self,
                                const GSList *vpn_configs,
                                const GSList *dev_configs,
                                const GSList *other_configs,
-                               const char *hostname);
+                               const char *hostname,
+                               const char *iface);
 
 /* For subclasses/plugins */
 
diff --git a/src/dnsmasq-manager/Makefile.in b/src/dnsmasq-manager/Makefile.in
index 89f55e5e..62c44c01 100644
--- a/src/dnsmasq-manager/Makefile.in
+++ b/src/dnsmasq-manager/Makefile.in
@@ -186,6 +186,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in
index 33539f51..dd596a81 100644
--- a/src/ip6-manager/Makefile.in
+++ b/src/ip6-manager/Makefile.in
@@ -187,6 +187,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c
index 4a5dee58..c7341390 100644
--- a/src/ip6-manager/nm-ip6-manager.c
+++ b/src/ip6-manager/nm-ip6-manager.c
@@ -27,6 +27,8 @@
 
 #include "nm-ip6-manager.h"
 #include "nm-netlink-monitor.h"
+#include "nm-netlink-utils.h"
+#include "nm-netlink-compat.h"
 #include "NetworkManagerUtils.h"
 #include "nm-marshal.h"
 #include "nm-logging.h"
@@ -44,7 +46,7 @@ typedef struct {
 	NMNetlinkMonitor *monitor;
 	GHashTable *devices;
 
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct nl_cache *addr_cache, *route_cache;
 
 	guint netlink_id;
@@ -549,11 +551,12 @@ process_addr (NMIP6Manager *manager, struct nl_msg *msg)
 	device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr));
 	if (!device) {
 		nm_log_dbg (LOGD_IP6, "ignoring message for unknown device");
+		rtnl_addr_put (rtnladdr);
 		return NULL;
 	}
 
 	old_size = nl_cache_nitems (priv->addr_cache);
-	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL);
+	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL);
 	rtnl_addr_put (rtnladdr);
 
 	/* The kernel will re-notify us of automatically-added addresses
@@ -589,11 +592,12 @@ process_route (NMIP6Manager *manager, struct nl_msg *msg)
 	device = nm_ip6_manager_get_device (manager, rtnl_route_get_oif (rtnlroute));
 	if (!device) {
 		nm_log_dbg (LOGD_IP6, "ignoring message for unknown device");
+		rtnl_route_put (rtnlroute);
 		return NULL;
 	}
 
 	old_size = nl_cache_nitems (priv->route_cache);
-	nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL);
+	nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL, NULL);
 	rtnl_route_put (rtnlroute);
 
 	/* As above in process_addr */
@@ -620,6 +624,11 @@ process_prefix (NMIP6Manager *manager, struct nl_msg *msg)
 
 	nm_log_dbg (LOGD_IP6, "processing netlink new prefix message");
 
+	if (!nlmsg_valid_hdr (nlmsg_hdr (msg), sizeof(*pmsg))) {
+		nm_log_dbg (LOGD_IP6, "ignoring invalid prefix message");
+		return NULL;
+	}
+
 	pmsg = (struct prefixmsg *) NLMSG_DATA (nlmsg_hdr (msg));
 	device = nm_ip6_manager_get_device (manager, pmsg->prefix_ifindex);
 
@@ -907,6 +916,13 @@ process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg)
 
 	ndmsg = (struct nduseroptmsg *) NLMSG_DATA (nlmsg_hdr (msg));
 
+	if (!nlmsg_valid_hdr (nlmsg_hdr (msg), sizeof (*ndmsg)) ||
+	    nlmsg_datalen (nlmsg_hdr (msg)) <
+		(ndmsg->nduseropt_opts_len + sizeof (*ndmsg))) {
+		nm_log_dbg (LOGD_IP6, "ignoring invalid nduseropt message");
+		return NULL;
+	}
+
 	if (ndmsg->nduseropt_family != AF_INET6 ||
 		ndmsg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
 		ndmsg->nduseropt_icmp_code != 0) {
@@ -966,6 +982,19 @@ process_newlink (NMIP6Manager *manager, struct nl_msg *msg)
 	struct nlattr *pi[IFLA_INET6_MAX + 1];
 	int err;
 
+	/* FIXME: we have to do this manually for now since libnl doesn't yet
+	 * support the IFLA_PROTINFO attribute of NEWLINK messages.  When it does,
+	 * we can get rid of this function and just grab IFLA_PROTINFO from
+	 * nm_ip6_device_sync_from_netlink(), then get the IFLA_INET6_FLAGS out of
+	 * the PROTINFO.
+	 */
+	err = nlmsg_parse (hdr, sizeof (*ifi), tb, IFLA_MAX, link_policy);
+	if (err < 0) {
+		nm_log_dbg (LOGD_IP6, "ignoring invalid newlink netlink message "
+				      "while parsing PROTINFO attribute");
+		return NULL;
+	}
+
 	ifi = nlmsg_data (hdr);
 	if (ifi->ifi_family != AF_INET6) {
 		nm_log_dbg (LOGD_IP6, "ignoring netlink message family %d", ifi->ifi_family);
@@ -979,18 +1008,6 @@ process_newlink (NMIP6Manager *manager, struct nl_msg *msg)
 		return NULL;
 	}
 
-	/* FIXME: we have to do this manually for now since libnl doesn't yet
-	 * support the IFLA_PROTINFO attribute of NEWLINK messages.  When it does,
-	 * we can get rid of this function and just grab IFLA_PROTINFO from
-	 * nm_ip6_device_sync_from_netlink(), then get the IFLA_INET6_FLAGS out of
-	 * the PROTINFO.
-	 */
-
-	err = nlmsg_parse (hdr, sizeof (*ifi), tb, IFLA_MAX, link_policy);
-	if (err < 0) {
-		nm_log_dbg (LOGD_IP6, "(%s): error parsing PROTINFO attribute", device->iface);
-		return NULL;
-	}
 	if (!tb[IFLA_PROTINFO]) {
 		nm_log_dbg (LOGD_IP6, "(%s): message had no PROTINFO attribute", device->iface);
 		return NULL;
@@ -1248,7 +1265,7 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
 		nm_ip6_route_set_dest (ip6route, dest);
 		nm_ip6_route_set_prefix (ip6route, rtnl_route_get_dst_len (rtnlroute));
 		nm_ip6_route_set_next_hop (ip6route, gateway);
-		metric = rtnl_route_get_metric (rtnlroute, 1);
+		rtnl_route_get_metric(rtnlroute, 1, &metric);
 		if (metric != UINT_MAX)
 			nm_ip6_route_set_metric (ip6route, metric);
 		nm_ip6_config_take_route (config, ip6route);
@@ -1344,8 +1361,10 @@ nm_ip6_manager_init (NMIP6Manager *manager)
 	                                     G_CALLBACK (netlink_notification), manager);
 
 	priv->nlh = nm_netlink_get_default_handle ();
-	priv->addr_cache = rtnl_addr_alloc_cache (priv->nlh);
-	priv->route_cache = rtnl_route_alloc_cache (priv->nlh);
+	rtnl_addr_alloc_cache (priv->nlh, &priv->addr_cache);
+	g_warn_if_fail (priv->addr_cache != NULL);
+	rtnl_route_alloc_cache (priv->nlh, NETLINK_ROUTE, NL_AUTO_PROVIDE, &priv->route_cache);
+	g_warn_if_fail (priv->route_cache != NULL);
 }
 
 static void
diff --git a/src/logging/Makefile.in b/src/logging/Makefile.in
index a85578d9..951cd2b6 100644
--- a/src/logging/Makefile.in
+++ b/src/logging/Makefile.in
@@ -183,6 +183,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in
index 2a054f70..5f83035f 100644
--- a/src/modem-manager/Makefile.in
+++ b/src/modem-manager/Makefile.in
@@ -189,6 +189,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 1823e5e6..debfbdf7 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -640,7 +640,7 @@ static void
 real_deactivate (NMModem *self, NMDevice *device)
 {
 	NMModemPrivate *priv;
-	const char *iface;
+	int ifindex;
 
 	g_return_if_fail (self != NULL);
 	g_return_if_fail (NM_IS_MODEM (self));
@@ -679,11 +679,11 @@ real_deactivate (NMModem *self, NMDevice *device)
 		break;
 	case MM_MODEM_IP_METHOD_STATIC:
 	case MM_MODEM_IP_METHOD_DHCP:
-		iface = nm_device_get_ip_iface (device);
+		ifindex = nm_device_get_ip_ifindex (device);
 		/* FIXME: use AF_UNSPEC here when we have IPv6 support */
-		nm_system_device_flush_routes_with_iface (iface, AF_INET);
-		nm_system_device_flush_addresses_with_iface (iface);
-		nm_system_device_set_up_down_with_iface (iface, FALSE, NULL);
+		nm_system_iface_flush_routes (ifindex, AF_INET);
+		nm_system_iface_flush_addresses (ifindex, AF_UNSPEC);
+		nm_system_iface_set_up (ifindex, FALSE, NULL);
 		break;
 	default:
 		nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method);
@@ -775,7 +775,7 @@ nm_modem_hw_is_up (NMModem *self, NMDevice *device)
 
 		state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
 		if (priv->pending_ip4_config || _state_is_active (state))
-			return nm_system_device_is_up (device);
+			return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 	}
 
 	return TRUE;
@@ -792,7 +792,7 @@ nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware)
 
 		state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
 		if (priv->pending_ip4_config || _state_is_active (state))
-			return nm_system_device_set_up_down (device, TRUE, no_firmware);
+			return nm_system_iface_set_up (nm_device_get_ip_ifindex (device), TRUE, no_firmware);
 	}
 
 	return TRUE;
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index 35b73670..8556c5bd 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -59,6 +59,7 @@
 #include "nm-logging.h"
 #include "nm-properties-changed-signal.h"
 #include "nm-dhcp-manager.h"
+#include "nm-netlink-utils.h"
 
 #include "nm-device-ethernet-glue.h"
 
@@ -546,19 +547,19 @@ real_take_down (NMDevice *dev)
 static gboolean
 real_hw_is_up (NMDevice *device)
 {
-	return nm_system_device_is_up (device);
+	return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 }
 
 static gboolean
 real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 {
-	return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+	return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-	nm_system_device_set_up_down (dev, FALSE, NULL);
+	nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL);
 }
 
 NMDevice *
@@ -677,7 +678,7 @@ _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail)
 	/* Can't change MAC address while device is up */
 	real_hw_take_down (dev);
 
-	success = nm_system_device_set_mac (iface, (struct ether_addr *) addr);
+	success = nm_system_iface_set_mac (nm_device_get_ip_ifindex (dev), (struct ether_addr *) addr);
 	if (success) {
 		/* MAC address succesfully changed; update the current MAC to match */
 		_update_hw_addr (self, addr);
@@ -1796,73 +1797,19 @@ wired_match_config (NMDevice *self, NMConnection *connection)
 	return TRUE;
 }
 
-typedef struct {
-	int ifindex;
-	NMIP4Address *addr;
-	gboolean found;
-} AddrData;
-
-static void
-check_one_address (struct nl_object *object, void *user_data)
-{
-	AddrData *data = user_data;
-	struct rtnl_addr *addr = (struct rtnl_addr *) object;
-	struct nl_addr *local;
-	struct in_addr tmp;
-
-	if (rtnl_addr_get_ifindex (addr) != data->ifindex)
-		return;
-	if (rtnl_addr_get_family (addr) != AF_INET)
-		return;
-
-	if (nm_ip4_address_get_prefix (data->addr) != rtnl_addr_get_prefixlen (addr))
-		return;
-
-	local = rtnl_addr_get_local (addr);
-	if (nl_addr_get_family (local) != AF_INET)
-		return;
-	if (nl_addr_get_len (local) != sizeof (struct in_addr))
-		return;
-	if (!nl_addr_get_binary_addr (local))
-		return;
-
-	memcpy (&tmp, nl_addr_get_binary_addr (local), nl_addr_get_len (local));
-	if (tmp.s_addr != nm_ip4_address_get_address (data->addr))
-		return;
-
-	/* Yay, found it */
-	data->found = TRUE;
-}
-
 static gboolean
 ip4_match_config (NMDevice *self, NMConnection *connection)
 {
 	NMSettingIP4Config *s_ip4;
-	struct nl_handle *nlh = NULL;
-	struct nl_cache *addr_cache = NULL;
 	int i, num;
 	GSList *leases, *iter;
 	NMDHCPManager *dhcp_mgr;
 	const char *method;
-	int ifindex;
-	AddrData check_data;
-
-	ifindex = nm_device_get_ifindex (self);
 
-	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	if (!s_ip4)
 		return FALSE;
 
-	/* Read all the device's IP addresses */
-	nlh = nm_netlink_get_default_handle ();
-	if (!nlh)
-		return FALSE;
-
-	addr_cache = rtnl_addr_alloc_cache (nlh);
-	if (!addr_cache)
-		return FALSE;
-	nl_cache_mngt_provide (addr_cache);
-
 	/* Get any saved leases that apply to this connection */
 	dhcp_mgr = nm_dhcp_manager_get ();
 	leases = nm_dhcp_manager_get_lease_config (dhcp_mgr,
@@ -1876,15 +1823,14 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
 
 		/* Find at least one lease's address on the device */
 		for (iter = leases; iter; iter = g_slist_next (iter)) {
-			NMIP4Config *addr = iter->data;
-
-			memset (&check_data, 0, sizeof (check_data));
-			check_data.ifindex = ifindex;
-			check_data.found = FALSE;
-			check_data.addr = nm_ip4_config_get_address (addr, 0);
-
-			nl_cache_foreach (addr_cache, check_one_address, &check_data);
-			if (check_data.found) {
+			NMIP4Config *ip4_config = iter->data;
+			NMIP4Address *addr = nm_ip4_config_get_address (ip4_config, 0);
+			struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) };
+
+			if (addr && nm_netlink_find_address (nm_device_get_ip_ifindex (self),
+			                                     AF_INET,
+			                                     &tmp,
+			                                     nm_ip4_address_get_prefix (addr))) {
 				found = TRUE; /* Yay, device has same address as a lease */
 				break;
 			}
@@ -1908,16 +1854,16 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
 
 	/* Everything below for static addressing */
 
-	/* Find all IP4 addresses of this connection in the device's address list */
+	/* Find all IP4 addresses of this connection on the device */
 	num = nm_setting_ip4_config_get_num_addresses (s_ip4);
 	for (i = 0; i < num; i++) {
-		memset (&check_data, 0, sizeof (check_data));
-		check_data.ifindex = ifindex;
-		check_data.found = FALSE;
-		check_data.addr = nm_setting_ip4_config_get_address (s_ip4, i);
+		NMIP4Address *addr = nm_setting_ip4_config_get_address (s_ip4, i);
+		struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) };
 
-		nl_cache_foreach (addr_cache, check_one_address, &check_data);
-		if (!check_data.found)
+		if (!nm_netlink_find_address (nm_device_get_ip_ifindex (self),
+		                              AF_INET,
+		                              &tmp,
+		                              nm_ip4_address_get_prefix (addr)))
 			return FALSE;
 	}
 
diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c
index 88322344..ae14279b 100644
--- a/src/nm-device-olpc-mesh.c
+++ b/src/nm-device-olpc-mesh.c
@@ -271,19 +271,19 @@ error:
 static gboolean
 real_hw_is_up (NMDevice *device)
 {
-	return nm_system_device_is_up (device);
+	return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 }
 
 static gboolean
 real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 {
-	return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+	return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-	nm_system_device_set_up_down (dev, FALSE, NULL);
+	nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL);
 }
 
 static gboolean
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 278d9a06..6fac0d03 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -1133,7 +1133,7 @@ out:
 static gboolean
 real_hw_is_up (NMDevice *device)
 {
-	return nm_system_device_is_up (device);
+	return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 }
 
 static gboolean
@@ -1142,13 +1142,13 @@ real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
 	if (!NM_DEVICE_WIFI_GET_PRIVATE (device)->enabled)
 		return FALSE;
 
-	return nm_system_device_set_up_down (device, TRUE, no_firmware);
+	return nm_system_iface_set_up (nm_device_get_ip_ifindex (device), TRUE, no_firmware);
 }
 
 static void
-real_hw_take_down (NMDevice *dev)
+real_hw_take_down (NMDevice *device)
 {
-	nm_system_device_set_up_down (dev, FALSE, NULL);
+	nm_system_iface_set_up (nm_device_get_ip_ifindex (device), FALSE, NULL);
 }
 
 static gboolean
@@ -1209,7 +1209,7 @@ _set_hw_addr (NMDeviceWifi *self, const guint8 *addr, const char *detail)
 	/* Can't change MAC address while device is up */
 	real_hw_take_down (dev);
 
-	success = nm_system_device_set_mac (iface, (struct ether_addr *) addr);
+	success = nm_system_iface_set_mac (nm_device_get_ip_ifindex (dev), (struct ether_addr *) addr);
 	if (success) {
 		/* MAC address succesfully changed; update the current MAC to match */
 		_update_hw_addr (self, addr);
diff --git a/src/nm-device.c b/src/nm-device.c
index 1301197a..d570d1bd 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -47,6 +47,8 @@
 #include "nm-utils.h"
 #include "nm-logging.h"
 #include "nm-netlink-monitor.h"
+#include "nm-netlink-utils.h"
+#include "nm-netlink-compat.h"
 #include "nm-setting-ip4-config.h"
 #include "nm-setting-ip6-config.h"
 #include "nm-setting-connection.h"
@@ -187,6 +189,8 @@ static void addrconf6_cleanup (NMDevice *self);
 static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release);
 static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release);
 
+static const char *reason_to_string (NMDeviceStateReason reason);
+
 
 static void
 device_interface_init (NMDeviceInterface *device_interface_class)
@@ -1591,16 +1595,15 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
 	NMSettingIP4Config *s_ip4;
 	NMActRequest *req;
 	NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
-	const char *ip_iface, *method = NULL;
+	const char *method = NULL;
+	int ifindex;
 
 	g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
 
-	/* Use the IP interface (not the control interface) for IP stuff */
-	ip_iface = nm_device_get_ip_iface (self);
-
 	/* Make sure the interface is up before trying to do anything with it */
-	if (!nm_system_device_is_up_with_iface (ip_iface))
-		nm_system_device_set_up_down_with_iface (ip_iface, TRUE, NULL);
+	ifindex = nm_device_get_ip_ifindex (self);
+	if (!nm_system_iface_is_up (ifindex))
+		nm_system_iface_set_up (ifindex, TRUE, NULL);
 
 	req = nm_device_get_act_request (self);
 	connection = nm_act_request_get_connection (req);
@@ -1680,10 +1683,10 @@ dhcp6_start (NMDevice *self,
 	 */
 	err = nm_system_set_ip6_route (priv->ip_iface ? priv->ip_ifindex : priv->ifindex,
 	                               &dest, 8, NULL, 256, 0, RTPROT_BOOT, RT_TABLE_LOCAL, NULL);
-	if (err && (nl_get_errno () != EEXIST)) {
+	if (err && (err != -NLE_EXIST)) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP6,
 		            "(%s): failed to add IPv6 multicast route: %s",
-		            priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror ());
+		            priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror (err));
 	}
 
 	s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
@@ -2522,7 +2525,7 @@ start_sharing (NMDevice *self)
 	add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", ip_iface, ip_iface);
 	add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, ip_iface);
 	add_share_rule (req, "filter", "FORWARD --destination %s/%s --out-interface %s --match state --state ESTABLISHED,RELATED --jump ACCEPT", str_addr, str_mask, ip_iface);
-	add_share_rule (req, "nat", "POSTROUTING --source %s/%s --destination ! %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
+	add_share_rule (req, "nat", "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
 
 	nm_act_request_set_shared (req, TRUE);
 
@@ -2820,11 +2823,12 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 	NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
 	gboolean tried_ipv6 = FALSE;
+	int ifindex, family;
 
 	g_return_if_fail (self != NULL);
 
-	nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason: %d).",
-	             nm_device_get_iface (self), reason);
+	nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason '%s') [%d]",
+	             nm_device_get_iface (self), reason_to_string (reason), reason);
 
 	/* Save whether or not we tried IPv6 for later */
 	if (NM_DEVICE_GET_PRIVATE (self)->ip6_manager)
@@ -2857,8 +2861,10 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
 	clear_act_request (self);
 
 	/* Take out any entries in the routing table and any IP address the device had. */
-	nm_system_device_flush_routes (self, tried_ipv6 ? AF_UNSPEC : AF_INET);
-	nm_system_device_flush_addresses (self, tried_ipv6 ? AF_UNSPEC : AF_INET);
+	ifindex = nm_device_get_ip_ifindex (self);
+	family = tried_ipv6 ? AF_UNSPEC : AF_INET;
+	nm_system_iface_flush_routes (ifindex, family);
+	nm_system_iface_flush_addresses (ifindex, family);
 	nm_device_update_ip4_address (self);	
 
 	/* Clean up nameservers and addresses */
@@ -3009,6 +3015,7 @@ nm_device_set_ip4_config (NMDevice *self,
 	gboolean success = TRUE;
 	NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL;
 	NMDnsManager *dns_mgr;
+	int ip_ifindex;
 
 	g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
 	g_return_val_if_fail (reason != NULL, FALSE);
@@ -3039,8 +3046,10 @@ nm_device_set_ip4_config (NMDevice *self,
 		/* Don't touch the device's actual IP config if the connection is
 		 * assumed when NM starts.
 		 */
-		if (!assumed)
-			success = nm_system_apply_ip4_config (ip_iface, new_config, nm_device_get_priority (self), diff);
+		if (!assumed) {
+			ip_ifindex = nm_device_get_ip_ifindex (self);
+			success = nm_system_apply_ip4_config (ip_ifindex, new_config, nm_device_get_priority (self), diff);
+		}
 
 		if (success || assumed) {
 			/* Export over D-Bus */
@@ -3112,12 +3121,14 @@ nm_device_set_ip6_config (NMDevice *self,
 	gboolean success = TRUE;
 	NMIP6ConfigCompareFlags diff = NM_IP6_COMPARE_FLAG_ALL;
 	NMDnsManager *dns_mgr;
+	int ip_ifindex;
 
 	g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
 	g_return_val_if_fail (reason != NULL, FALSE);
 
 	priv = NM_DEVICE_GET_PRIVATE (self);
 	ip_iface = nm_device_get_ip_iface (self);
+	ip_ifindex = nm_device_get_ip_ifindex (self);
 
 	old_config = priv->ip6_config;
 
@@ -3143,7 +3154,7 @@ nm_device_set_ip6_config (NMDevice *self,
 		 * assumed when NM starts.
 		 */
 		if (!assumed)
-			success = nm_system_apply_ip6_config (ip_iface, new_config, nm_device_get_priority (self), diff);
+			success = nm_system_apply_ip6_config (ip_ifindex, new_config, nm_device_get_priority (self), diff);
 
 		if (success || assumed) {
 			/* Export over D-Bus */
@@ -3395,7 +3406,7 @@ set_property (GObject *object, guint prop_id,
 		priv->iface = g_value_dup_string (value);
 		if (priv->iface) {
 			priv->ifindex = nm_netlink_iface_to_index (priv->iface);
-			if (priv->ifindex < 0) {
+			if (priv->ifindex <= 0) {
 				nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", priv->iface);
 			}
 		}
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f5782254..9200f348 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -214,7 +214,8 @@ typedef struct {
 	gboolean net_enabled;
 
 	NMVPNManager *vpn_manager;
-	guint vpn_manager_id;
+	gulong vpn_manager_activated_id;
+	gulong vpn_manager_deactivated_id;
 
 	NMModemManager *modem_manager;
 	guint modem_added_id;
@@ -377,6 +378,18 @@ manager_sleeping (NMManager *self)
 }
 
 static void
+vpn_manager_connection_activated_cb (NMVPNManager *manager,
+                                     NMVPNConnection *vpn,
+                                     NMVPNConnectionState state,
+                                     NMVPNConnectionStateReason reason,
+                                     gpointer user_data)
+{
+	/* Update timestamp for the VPN connection */
+	nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_vpn_connection_get_connection (vpn)),
+	                                         (guint64) time (NULL));
+}
+
+static void
 vpn_manager_connection_deactivated_cb (NMVPNManager *manager,
                                        NMVPNConnection *vpn,
                                        NMVPNConnectionState state,
@@ -3159,9 +3172,13 @@ dispose (GObject *object)
 
 	g_object_unref (priv->settings);
 
-	if (priv->vpn_manager_id) {
-		g_source_remove (priv->vpn_manager_id);
-		priv->vpn_manager_id = 0;
+	if (priv->vpn_manager_activated_id) {
+		g_source_remove (priv->vpn_manager_activated_id);
+		priv->vpn_manager_activated_id = 0;
+	}
+	if (priv->vpn_manager_deactivated_id) {
+		g_source_remove (priv->vpn_manager_deactivated_id);
+		priv->vpn_manager_deactivated_id = 0;
 	}
 	g_object_unref (priv->vpn_manager);
 
@@ -3402,6 +3419,7 @@ static gboolean
 periodic_update_active_connection_timestamps (gpointer user_data)
 {
 	NMManager *manager = NM_MANAGER (user_data);
+	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
 	GPtrArray *active;
 	int i;
 
@@ -3416,6 +3434,15 @@ periodic_update_active_connection_timestamps (gpointer user_data)
 		if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
 			nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)),
 			                                         (guint64) time (NULL));
+		else {
+			/* The connection is probably VPN */
+			NMVPNConnection *vpn_con;
+
+			vpn_con = nm_vpn_manager_get_vpn_connection_for_active (priv->vpn_manager, active_path);
+			if (vpn_con && nm_vpn_connection_get_vpn_state (vpn_con) == NM_VPN_CONNECTION_STATE_ACTIVATED)
+				nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_vpn_connection_get_connection (vpn_con)),
+				                                         (guint64) time (NULL));
+		}
 	}
 
 	return TRUE;
@@ -3426,7 +3453,7 @@ nm_manager_init (NMManager *manager)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
 	DBusGConnection *g_connection;
-	guint id, i;
+	guint i;
 	GFile *file;
 
 	/* Initialize rfkill structures and states */
@@ -3471,9 +3498,10 @@ nm_manager_init (NMManager *manager)
 	                                           G_CALLBACK (modem_removed), manager);
 
 	priv->vpn_manager = nm_vpn_manager_get ();
-	id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated",
-	                       G_CALLBACK (vpn_manager_connection_deactivated_cb), manager);
-	priv->vpn_manager_id = id;
+	priv->vpn_manager_activated_id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-activated",
+	                                                   G_CALLBACK (vpn_manager_connection_activated_cb), manager);
+	priv->vpn_manager_deactivated_id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated",
+	                                                   G_CALLBACK (vpn_manager_connection_deactivated_cb), manager);
 
 	g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
 
diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c
new file mode 100644
index 00000000..e91a1ff2
--- /dev/null
+++ b/src/nm-netlink-compat.c
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2011 Caixa Magica Software.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include "nm-netlink-compat.h"
+
+#ifndef HAVE_LIBNL1
+struct rtnl_nexthop *
+nm_netlink_get_nh (struct rtnl_route * route)
+{
+	int hops;
+
+	hops = rtnl_route_get_nnexthops (route);
+	g_return_val_if_fail(hops > 0, NULL);
+	return rtnl_route_nexthop_n (route, 0);
+}
+
+int
+rtnl_route_get_oif (struct rtnl_route * route)
+{
+	struct rtnl_nexthop * nh;
+
+	nh = nm_netlink_get_nh(route);
+	g_return_val_if_fail(nh, -NLE_OBJ_NOTFOUND);
+	return rtnl_route_nh_get_ifindex (nh);
+}
+
+int
+rtnl_route_set_oif (struct rtnl_route * route, int ifindex)
+{
+	struct rtnl_nexthop * nh;
+
+	nh = rtnl_route_nh_alloc();
+	rtnl_route_nh_set_ifindex(nh, ifindex);
+	rtnl_route_add_nexthop(route, nh);
+	return 0;
+}
+
+struct nl_addr *
+rtnl_route_get_gateway (struct rtnl_route * route)
+{
+	struct rtnl_nexthop * nh;
+
+	nh = nm_netlink_get_nh(route);
+	g_return_val_if_fail(nh, NULL);
+	return rtnl_route_nh_get_gateway(nh);
+}
+
+int
+rtnl_route_set_gateway (struct rtnl_route * route, struct nl_addr * gw_addr)
+{
+	struct rtnl_nexthop * nh;
+
+	nh = nm_netlink_get_nh(route);
+	g_return_val_if_fail(nh, -NLE_OBJ_NOTFOUND);
+
+	rtnl_route_nh_set_gateway(nh, gw_addr);
+	return 0;
+}
+
+int
+rtnl_route_get_dst_len(struct rtnl_route * rtnlroute)
+{
+	struct nl_addr * dst;
+
+	dst = rtnl_route_get_dst(rtnlroute);
+	return nl_addr_get_prefixlen(dst);
+}
+#endif
+
+#ifdef HAVE_LIBNL1
+int
+nl_compat_error (int err)
+{
+	err = abs (err);
+
+	if (err == EEXIST)
+		err = NLE_EXIST;
+	else if (err == ENOENT || err == ESRCH)
+		err = NLE_OBJ_NOTFOUND;
+	else if (err == ERANGE)
+		err = NLE_RANGE;
+
+	return -err;
+}
+#endif
diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h
new file mode 100644
index 00000000..f6225c70
--- /dev/null
+++ b/src/nm-netlink-compat.h
@@ -0,0 +1,198 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2011 Caixa Magica Software.
+ */
+
+#ifndef NM_NETLINK_COMPAT_H
+#define NM_NETLINK_COMPAT_H
+
+#include <errno.h>
+
+#include <netlink/netlink.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/link.h>
+#include <netlink/route/route.h>
+#include <netlink/route/addr.h>
+
+
+#include <netlink/netlink.h>
+#include <netlink/cache.h>
+#include <netlink/utils.h>
+#include <netlink/data.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/route.h>
+#include <netlink/route/link.h>
+#include <netlink/route/nexthop.h>
+
+#include <config.h>
+
+/* libnl-1 API compatibility for libnl-2/3*/
+#ifndef HAVE_LIBNL1
+
+struct rtnl_nexthop * nm_netlink_get_nh(struct rtnl_route *);
+int rtnl_route_get_oif(struct rtnl_route *);
+int rtnl_route_set_oif(struct rtnl_route *, int);
+int rtnl_route_set_gateway(struct rtnl_route *, struct nl_addr *);
+int rtnl_route_get_dst_len(struct rtnl_route *);
+struct nl_addr * rtnl_route_get_gateway(struct rtnl_route *);
+#endif
+
+/* libnl-2 API compatibility for libnl-3 */
+#ifdef HAVE_LIBNL3
+static inline int
+__rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache)
+{
+       return rtnl_link_alloc_cache (h, AF_UNSPEC, cache);
+}
+#define rtnl_link_alloc_cache __rtnl_link_alloc_cache
+#endif
+
+/* libnl-1.0 compat functions */
+#ifdef HAVE_LIBNL1
+
+#define nl_sock nl_handle
+
+/* libnl-1.0 functions with similar prototypes */
+#define nl_socket_alloc nl_handle_alloc
+#define nl_socket_alloc_cb nl_handle_alloc_cb
+#define nl_socket_free nl_handle_destroy
+#define nl_socket_set_passcred nl_set_passcred
+#define nl_socket_disable_seq_check nl_disable_sequence_check
+#define rtnl_route_set_priority rtnl_route_set_prio
+#define nlmsg_datalen nlmsg_len
+
+/* auxiliary functions */
+int nl_compat_error (int);
+
+/* libnl-1.0 functions with modified prototypes in libnl-2/3*/
+static inline const char * 
+__nl_geterror (int err)
+{
+        /* err is set, can be parsed */
+        return nl_geterror ();
+}
+#define nl_geterror __nl_geterror
+
+static inline int
+__rtnl_addr_alloc_cache (struct nl_sock *h, struct nl_cache **cache)
+{
+	g_return_val_if_fail (cache != NULL, -EINVAL);
+
+	*cache = rtnl_addr_alloc_cache (h);
+	return *cache ? 0 : -ENOMEM;
+}
+#define rtnl_addr_alloc_cache __rtnl_addr_alloc_cache
+
+static inline int
+__rtnl_route_alloc_cache (struct nl_sock *h, int family, int flags, struct nl_cache **cache)
+{
+	g_return_val_if_fail (cache != NULL, -EINVAL);
+
+	*cache = rtnl_route_alloc_cache (h);
+	return *cache ? 0 : -ENOMEM;
+}
+#define rtnl_route_alloc_cache __rtnl_route_alloc_cache
+
+static inline int
+__rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache)
+{
+	g_return_val_if_fail (cache != NULL, -EINVAL);
+
+	*cache = rtnl_link_alloc_cache (h);
+	return *cache ? 0 : -ENOMEM;
+}
+#define rtnl_link_alloc_cache __rtnl_link_alloc_cache
+
+static inline int
+__rtnl_route_get_metric (struct rtnl_route *route, int metric, unsigned int *value)
+{
+	g_return_val_if_fail (value != NULL, -EINVAL);
+
+	*value = rtnl_route_get_metric (route, metric);
+	return 0;
+}
+#define rtnl_route_get_metric __rtnl_route_get_metric
+
+static inline int
+__rtnl_addr_add (struct nl_sock *h, struct rtnl_addr *addr, int flags)
+{
+	return nl_compat_error (rtnl_addr_add (h, addr, flags));
+}
+#define rtnl_addr_add __rtnl_addr_add
+
+static inline int
+__rtnl_route_add (struct nl_sock *sk, struct rtnl_route *route, int flags)
+{
+	return nl_compat_error (rtnl_route_add (sk, route, flags));
+}
+#define rtnl_route_add __rtnl_route_add
+
+static inline int
+rtnl_route_delete (struct nl_sock *h, struct rtnl_route *route, int flags)
+{
+	return nl_compat_error (rtnl_route_del (h, route, flags));
+}
+#define rtnl_route_del rtnl_route_delete
+
+static inline int
+__rtnl_link_change (struct nl_sock *h, struct rtnl_link *old, struct rtnl_link *tmpl, int flags)
+{
+	return nl_compat_error (rtnl_link_change (h, old, tmpl,flags));
+}
+#define rtnl_link_change __rtnl_link_change
+
+static inline int
+__nl_cache_include (struct nl_cache *cache, struct nl_object *obj, change_func_t cb, void *data)
+{
+	return nl_cache_include (cache, obj, cb);
+}
+#define nl_cache_include __nl_cache_include
+
+#define NLE_SUCCESS             0
+#define NLE_FAILURE             1
+#define NLE_INTR                2
+#define NLE_BAD_SOCK            3
+#define NLE_AGAIN               4
+#define NLE_NOMEM               5
+#define NLE_EXIST               6
+#define NLE_INVAL               7
+#define NLE_RANGE               8
+#define NLE_MSGSIZE             9
+#define NLE_OPNOTSUPP           10
+#define NLE_AF_NOSUPPORT        11
+#define NLE_OBJ_NOTFOUND        12
+#define NLE_NOATTR              13
+#define NLE_MISSING_ATTR        14
+#define NLE_AF_MISMATCH         15
+#define NLE_SEQ_MISMATCH        16
+#define NLE_MSG_OVERFLOW        17
+#define NLE_MSG_TRUNC           18
+#define NLE_NOADDR              19
+#define NLE_SRCRT_NOSUPPORT     20
+#define NLE_MSG_TOOSHORT        21
+#define NLE_MSGTYPE_NOSUPPORT   22
+#define NLE_OBJ_MISMATCH        23
+#define NLE_NOCACHE             24
+#define NLE_BUSY                25
+#define NLE_PROTO_MISMATCH      26
+#define NLE_NOACCESS            27
+#define NLE_PERM                28
+#define NLE_PKTLOC_FILE         29
+#endif
+
+#endif /* NM_NETLINK_COMPAT_H */
diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c
index 13b3ab98..fb859814 100644
--- a/src/nm-netlink-monitor.c
+++ b/src/nm-netlink-monitor.c
@@ -45,6 +45,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
+#include "nm-netlink-compat.h"
 #include "nm-netlink-monitor.h"
 #include "nm-logging.h"
 
@@ -58,12 +59,12 @@
 
 typedef struct {
 	/* Async event listener connection */
-	struct nl_handle *nlh_event;
+	struct nl_sock *nlh_event;
 	GIOChannel *	  io_channel;
 	guint             event_id;
 
 	/* Sync/blocking request/response connection */
-	struct nl_handle *nlh_sync;
+	struct nl_sock *nlh_sync;
 	struct nl_cache * link_cache;
 
 	guint request_status_id;
@@ -98,7 +99,7 @@ link_msg_handler (struct nl_object *obj, void *arg)
 		error = g_error_new (NM_NETLINK_MONITOR_ERROR,
 		                     NM_NETLINK_MONITOR_ERROR_BAD_ALLOC,
 		                     _("error processing netlink message: %s"),
-		                     nl_geterror ());
+		                     nl_geterror (ENOMEM));
 		g_signal_emit (self, signals[ERROR], 0, error);
 		g_error_free (error);
 		return;
@@ -130,7 +131,7 @@ link_msg_handler (struct nl_object *obj, void *arg)
 static int
 event_msg_recv (struct nl_msg *msg, void *arg)
 {
-	struct nl_handle *nlh = arg;
+	struct nl_sock *nlh = arg;
 	struct nlmsghdr *hdr = nlmsg_hdr (msg);
 	struct ucred *creds = nlmsg_get_creds (msg);
 	const struct sockaddr_nl *snl;
@@ -195,6 +196,7 @@ event_handler (GIOChannel *channel,
 	NMNetlinkMonitor *self = (NMNetlinkMonitor *) user_data;
 	NMNetlinkMonitorPrivate *priv;
 	GError *error = NULL;
+	int err;
 
 	g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), TRUE);
 
@@ -225,11 +227,12 @@ event_handler (GIOChannel *channel,
 	g_return_val_if_fail (!(io_condition & ~EVENT_CONDITIONS), FALSE);
 
 	/* Process the netlink messages */
-	if (nl_recvmsgs_default (priv->nlh_event) < 0) {
+	err = nl_recvmsgs_default (priv->nlh_event);
+	if (err < 0) {
 		error = g_error_new (NM_NETLINK_MONITOR_ERROR,
 		                     NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE,
 		                     _("error processing netlink message: %s"),
-		                     nl_geterror ());
+		                     nl_geterror (err));
 		g_signal_emit (self, signals[ERROR], 0, error);
 		g_error_free (error);
 	}
@@ -238,32 +241,35 @@ event_handler (GIOChannel *channel,
 }
 
 static gboolean
-nlh_setup (struct nl_handle *nlh,
+nlh_setup (struct nl_sock *nlh,
            nl_recvmsg_msg_cb_t valid_func,
            gpointer cb_data,
            GError **error)
 {
+	int err;
+
 	nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, cb_data);
 
 	if (valid_func)
 		nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data);
 
-	if (nl_connect (nlh, NETLINK_ROUTE) < 0) {
+	err = nl_connect (nlh, NETLINK_ROUTE);
+	if (err < 0) {
 		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT,
 		             _("unable to connect to netlink for monitoring link status: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		return FALSE;
 	}
 
 	/* Enable unix socket peer credentials which we use for verifying that the
 	 * sender of the message is actually the kernel.
 	 */
-	if (nl_set_passcred (nlh, 1) < 0) {
+	if (nl_socket_set_passcred (nlh, 1) < 0) {
 		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT,
 		             _("unable to enable netlink handle credential passing: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		return FALSE;
 	}
 
@@ -276,27 +282,24 @@ event_connection_setup (NMNetlinkMonitor *self, GError **error)
 	NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);
 	GError *channel_error = NULL;
 	GIOFlags channel_flags;
-	struct nl_cb *cb;
 	int fd;
 
 	g_return_val_if_fail (priv->io_channel == NULL, FALSE);
 
 	/* Set up the event listener connection */
-	cb = nl_cb_alloc (NL_CB_DEFAULT);
-	priv->nlh_event = nl_handle_alloc_cb (cb);
-	nl_cb_put (cb);
+	priv->nlh_event = nl_socket_alloc ();
 	if (!priv->nlh_event) {
 		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE,
 		             _("unable to allocate netlink handle for monitoring link status: %s"),
-		             nl_geterror ());
+		             nl_geterror (ENOMEM));
 		goto error;
 	}
 
 	if (!nlh_setup (priv->nlh_event, event_msg_ready, self, error))
 		goto error;
 
-	nl_disable_sequence_check (priv->nlh_event);
+	nl_socket_disable_seq_check (priv->nlh_event);
 
 	/* Subscribe to the LINK group for internal carrier signals */
 	if (!nm_netlink_monitor_subscribe (self, RTNLGRP_LINK, error))
@@ -327,7 +330,7 @@ error:
 		nm_netlink_monitor_close_connection (self);
 
 	if (priv->nlh_event) {
-		nl_handle_destroy (priv->nlh_event);
+		nl_socket_free (priv->nlh_event);
 		priv->nlh_event = NULL;
 	}
 
@@ -338,20 +341,18 @@ static gboolean
 sync_connection_setup (NMNetlinkMonitor *self, GError **error)
 {
 	NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);
-	struct nl_cb *cb;
 #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
 	struct nl_cache *addr_cache;
 #endif
+	int err;
 
 	/* Set up the event listener connection */
-	cb = nl_cb_alloc (NL_CB_DEFAULT);
-	priv->nlh_sync = nl_handle_alloc_cb (cb);
-	nl_cb_put (cb);
+	priv->nlh_sync = nl_socket_alloc ();
 	if (!priv->nlh_sync) {
 		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE,
 		             _("unable to allocate netlink handle for monitoring link status: %s"),
-		             nl_geterror ());
+		             nl_geterror (ENOMEM));
 		goto error;
 	}
 
@@ -365,16 +366,18 @@ sync_connection_setup (NMNetlinkMonitor *self, GError **error)
 	 * result, most addresses will not compare as equal even to
 	 * themselves, busting caching.
 	 */
-	addr_cache = rtnl_addr_alloc_cache (priv->nlh_sync);
+	rtnl_addr_alloc_cache (priv->nlh_sync, &addr_cache);
+	g_warn_if_fail (addr_cache != NULL);
 	nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80;
 	nl_cache_free (addr_cache);
 #endif
 
-	if ((priv->link_cache = rtnl_link_alloc_cache (priv->nlh_sync)) == NULL) {
+	err = rtnl_link_alloc_cache (priv->nlh_sync, &priv->link_cache);
+	if (err < 0) {
 		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE,
 		             _("unable to allocate netlink link cache for monitoring link status: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		goto error;
 	}
 	nl_cache_mngt_provide (priv->link_cache);
@@ -388,7 +391,7 @@ error:
 	}
 
 	if (priv->nlh_sync) {
-		nl_handle_destroy (priv->nlh_sync);
+		nl_socket_free (priv->nlh_sync);
 		priv->nlh_sync = NULL;
 	}
 
@@ -483,7 +486,7 @@ gboolean
 nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error)
 {
 	NMNetlinkMonitorPrivate *priv;
-	int subs;
+	int subs, err;
 
 	g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE);
 
@@ -496,11 +499,12 @@ nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error)
 
 	subs = get_subs (self, group) + 1;
 	if (subs == 1) {
-		if (nl_socket_add_membership (priv->nlh_event, group) < 0) {
+		err = nl_socket_add_membership (priv->nlh_event, group);
+		if (err < 0) {
 			g_set_error (error, NM_NETLINK_MONITOR_ERROR,
 			             NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP,
 			             _("unable to join netlink group: %s"),
-			             nl_geterror ());
+			             nl_geterror (err));
 			return FALSE;
 		}
 	}
@@ -558,15 +562,17 @@ deferred_emit_carrier_state (gpointer user_data)
 {
 	NMNetlinkMonitor *self = NM_NETLINK_MONITOR (user_data);
 	NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);
+	int err;
 
 	priv->request_status_id = 0;
 
 	/* Update the link cache with latest state, and if there are no errors
 	 * emit the link states for all the interfaces in the cache.
 	 */
-	if (nl_cache_refill (priv->nlh_sync, priv->link_cache)) {
-		nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror ());
-	} else
+	err = nl_cache_refill (priv->nlh_sync, priv->link_cache);
+	if (err < 0)
+		nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror (err));
+	else
 		nl_cache_foreach_filter (priv->link_cache, NULL, link_msg_handler, self);
 
 	return FALSE;
@@ -614,6 +620,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self,
 	NMNetlinkMonitorPrivate *priv;
 	GetFlagsInfo info;
 	struct rtnl_link *filter;
+	int err;
 
 	g_return_val_if_fail (self != NULL, FALSE);
 	g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE);
@@ -622,12 +629,13 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self,
 	priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);
 
 	/* Update the link cache with the latest information */
-	if (nl_cache_refill (priv->nlh_sync, priv->link_cache)) {
+	err = nl_cache_refill (priv->nlh_sync, priv->link_cache);
+	if (err < 0) {
 		g_set_error (error,
 		             NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE,
 		             _("error updating link cache: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		return FALSE;
 	}
 
@@ -640,7 +648,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self,
 		             NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE,
 		             _("error updating link cache: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		return FALSE;
 	}
 
@@ -651,7 +659,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self,
 		             NM_NETLINK_MONITOR_ERROR,
 		             NM_NETLINK_MONITOR_ERROR_BAD_ALLOC,
 		             _("error processing netlink message: %s"),
-		             nl_geterror ());
+		             nl_geterror (err));
 		return FALSE;
 	}
 	rtnl_link_set_ifindex (filter, ifindex);
@@ -678,11 +686,11 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self,
 
 /***************************************************************/
 
-struct nl_handle *
+struct nl_sock *
 nm_netlink_get_default_handle (void)
 {
 	NMNetlinkMonitor *self;
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 
 	self = nm_netlink_monitor_get ();
 	nlh = NM_NETLINK_MONITOR_GET_PRIVATE (self)->nlh_sync;
@@ -796,12 +804,12 @@ finalize (GObject *object)
 	}
 
 	if (priv->nlh_event) {
-		nl_handle_destroy (priv->nlh_event);
+		nl_socket_free (priv->nlh_event);
 		priv->nlh_event = NULL;
 	}
 
 	if (priv->nlh_sync) {
-		nl_handle_destroy (priv->nlh_sync);
+		nl_socket_free (priv->nlh_sync);
 		priv->nlh_sync = NULL;
 	}
 
diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h
index 8b57a312..5c1fa339 100644
--- a/src/nm-netlink-monitor.h
+++ b/src/nm-netlink-monitor.h
@@ -90,10 +90,12 @@ gboolean          nm_netlink_monitor_get_flags_sync   (NMNetlinkMonitor *monitor
                                                        guint32 *ifflags,
                                                        GError **error);
 
+#include "nm-netlink-compat.h"
+
 /* Generic utility functions */
 int               nm_netlink_iface_to_index     (const char *iface);
 char *            nm_netlink_index_to_iface     (int idx);
 struct rtnl_link *nm_netlink_index_to_rtnl_link (int idx);
-struct nl_handle *nm_netlink_get_default_handle (void);
+struct nl_sock *  nm_netlink_get_default_handle (void);
 
 #endif  /* NM_NETLINK_MONITOR_H */
diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c
new file mode 100644
index 00000000..743f9465
--- /dev/null
+++ b/src/nm-netlink-utils.c
@@ -0,0 +1,423 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ */
+
+#include "logging/nm-logging.h"
+#include "nm-netlink-utils.h"
+#include "nm-netlink-monitor.h"
+#include "nm-netlink-compat.h"
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netlink/netlink.h>
+#include <netlink/addr.h>
+#include <netlink/route/addr.h>
+
+#include <errno.h>
+
+typedef struct {
+	int ifindex;
+	int family;
+	void *addr;
+	int addrlen;
+	int prefix;
+	gboolean found;
+} FindAddrInfo;
+
+static void
+find_one_address (struct nl_object *object, void *user_data)
+{
+	FindAddrInfo *info = user_data;
+	struct rtnl_addr *addr = (struct rtnl_addr *) object;
+	struct nl_addr *local;
+	void *binaddr;
+
+	if (info->found)
+		return;
+
+	if (rtnl_addr_get_ifindex (addr) != info->ifindex)
+		return;
+	if (rtnl_addr_get_family (addr) != info->family)
+		return;
+
+	if (rtnl_addr_get_prefixlen (addr) != info->prefix)
+		return;
+
+	local = rtnl_addr_get_local (addr);
+	if (nl_addr_get_family (local) != info->family)
+		return;
+	if (nl_addr_get_len (local) != info->addrlen)
+		return;
+	binaddr = nl_addr_get_binary_addr (local);
+	if (binaddr) {
+		if (memcmp (binaddr, info->addr, info->addrlen) == 0)
+			info->found = TRUE; /* Yay, found it */
+	}
+}
+
+/**
+ * nm_netlink_find_address:
+ * @ifindex: interface index
+ * @family: address family, either AF_INET or AF_INET6
+ * @addr: binary address, either struct in_addr* or struct in6_addr*
+ * @prefix: prefix length
+ *
+ * Searches for a matching address on the given interface.
+ *
+ * Returns: %TRUE if the given address was found on the interface, %FALSE if it
+ * was not found or an error occurred.
+ **/
+gboolean
+nm_netlink_find_address (int ifindex,
+                         int family,
+                         void *addr,  /* struct in_addr or struct in6_addr */
+                         int prefix)
+{
+	struct nl_sock *nlh = NULL;
+	struct nl_cache *cache = NULL;
+	FindAddrInfo info;
+
+	g_return_val_if_fail (ifindex > 0, FALSE);
+	g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE);
+	g_return_val_if_fail (addr != NULL, FALSE);
+	g_return_val_if_fail (prefix >= 0, FALSE);
+
+	memset (&info, 0, sizeof (info));
+	info.ifindex = ifindex;
+	info.family = family;
+	info.prefix = prefix;
+	info.addr = addr;
+	if (family == AF_INET)
+		info.addrlen = sizeof (struct in_addr);
+	else if (family == AF_INET6)
+		info.addrlen = sizeof (struct in6_addr);
+	else
+		g_assert_not_reached ();
+
+	nlh = nm_netlink_get_default_handle ();
+	if (nlh) {
+		rtnl_addr_alloc_cache(nlh, &cache);
+		if (cache) {
+			nl_cache_mngt_provide (cache);
+			nl_cache_foreach (cache, find_one_address, &info);
+			nl_cache_free (cache);
+		}
+	}
+	return info.found;
+}
+
+struct rtnl_route *
+nm_netlink_route_new (int ifindex,
+                      int family,
+                      int mss,
+                      ...)
+{
+	va_list var_args;
+	struct rtnl_route *route;
+	NmNlProp prop = NMNL_PROP_INVALID;
+	int value;
+
+	route = rtnl_route_alloc ();
+	g_return_val_if_fail (route != NULL, NULL);
+
+	if (ifindex >= 0)
+		rtnl_route_set_oif (route, ifindex);
+	if (family != AF_UNSPEC)
+		rtnl_route_set_family (route, family);
+	if (mss > 0)
+		rtnl_route_set_metric (route, RTAX_ADVMSS, mss);
+
+	va_start (var_args, mss);
+	prop = va_arg (var_args, NmNlProp);
+	while (prop != NMNL_PROP_INVALID) {
+		value = va_arg (var_args, int);
+
+		if (prop == NMNL_PROP_PROT && value != RTPROT_UNSPEC)
+			rtnl_route_set_protocol (route, value);
+		else if (prop == NMNL_PROP_TABLE && value != RT_TABLE_UNSPEC)
+			rtnl_route_set_table (route, value);
+		else if (prop == NMNL_PROP_SCOPE && value != RT_SCOPE_NOWHERE)
+			rtnl_route_set_scope (route, value);
+		else if (prop == NMNL_PROP_PRIO && value > 0)
+			rtnl_route_set_priority (route, value);
+
+		prop = va_arg (var_args, NmNlProp);
+	}
+	va_end (var_args);
+
+	return route;
+}
+
+/**
+ * nm_netlink_route_add:
+ * @route: the route to add
+ *
+ * Returns: zero if succeeded or the netlink error otherwise.
+ **/
+int nm_netlink_route_add(struct rtnl_route * route,
+			 int family,
+			 const void * dest, /* in_addr or in6_addr */
+			 int dest_prefix,
+			 const void * gateway, /* in_addr or in6_addr */
+			 int flags)
+{
+	struct nl_sock * sk;
+	struct nl_addr * dest_addr, * gw_addr;
+	void * tmp_addr;
+	int addrlen, err, log;
+
+	if(family == AF_INET) {
+		addrlen = sizeof(struct in_addr);
+		log = LOGD_IP4;
+	}
+	else if (family == AF_INET6) {
+		addrlen = sizeof(struct in6_addr);
+		log = LOGD_IP6;
+	} else {
+		g_assert_not_reached ();
+	}
+
+
+	sk = nm_netlink_get_default_handle();
+
+	/* Build up the destination address */
+	if (dest) {
+		/* Copy to preserve const */
+		tmp_addr = g_malloc0(addrlen);
+		memcpy(tmp_addr, dest, addrlen);
+
+		dest_addr = nl_addr_build (family, tmp_addr, addrlen);
+		g_free(tmp_addr);
+
+		g_return_val_if_fail (dest_addr != NULL, -NLE_INVAL);
+		nl_addr_set_prefixlen (dest_addr, dest_prefix);
+
+		rtnl_route_set_dst (route, dest_addr);
+		nl_addr_put (dest_addr);
+	}
+
+	/* Build up the gateway address */
+	if (gateway) {
+		tmp_addr = g_malloc0(addrlen);
+		memcpy(tmp_addr, gateway, addrlen);
+
+		gw_addr = nl_addr_build (family, tmp_addr, addrlen);
+		g_free(tmp_addr);
+
+		if (gw_addr) {
+			nl_addr_set_prefixlen (gw_addr, 0);
+			rtnl_route_set_gateway (route, gw_addr);
+			rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
+			nl_addr_put(gw_addr);
+		} else {
+			nm_log_err (LOGD_DEVICE | log, "Invalid gateway");
+		}
+	}
+
+	err = rtnl_route_add (sk, route, flags);
+
+	/* LIBNL Bug: Aliased ESRCH */
+	if (err == -NLE_FAILURE)
+		err = -NLE_OBJ_NOTFOUND;
+
+	if (err)
+		nm_log_warn (LOGD_DEVICE | log,
+                             "Failed to add route %s",
+                             nl_geterror(err));
+
+	return err;
+}
+
+/**
+ * nm_netlink_route_delete:
+ * @route: the route to delete
+ *
+ * Returns: %TRUE if the request was successful, %FALSE if it failed
+ **/
+gboolean
+nm_netlink_route_delete (struct rtnl_route *route)
+{
+	struct nl_sock *nlh;
+	int err = 0;
+
+	g_return_val_if_fail (route != NULL, FALSE);
+
+	nlh = nm_netlink_get_default_handle ();
+	err = rtnl_route_delete (nlh, route, 0);
+
+	if (err)
+		nm_log_dbg (LOGD_IP4 | LOGD_IP6, "%s (%d)", nl_geterror(err), err);
+
+	/* Workaround libnl BUG: ESRCH is aliased to generic NLE_FAILURE
+	 * See: http://git.kernel.org/?p=libs/netlink/libnl.git;a=commit;h=7e9d5f */
+	if (err == -NLE_FAILURE)
+		err = -NLE_OBJ_NOTFOUND;
+
+	return (err && (err != -NLE_OBJ_NOTFOUND) && (err != -NLE_RANGE) ) ? FALSE : TRUE;
+}
+
+
+static void
+dump_route (struct rtnl_route *route)
+{
+	char buf6[INET6_ADDRSTRLEN];
+	char buf4[INET_ADDRSTRLEN];
+	struct nl_addr *nl;
+	struct in6_addr *addr6 = NULL;
+	struct in_addr *addr4 = NULL;
+	int prefixlen = 0;
+	const char *sf = "UNSPEC";
+	int family = rtnl_route_get_family (route);
+	guint32 log_level = LOGD_IP4 | LOGD_IP6;
+
+	memset (buf6, 0, sizeof (buf6));
+	memset (buf4, 0, sizeof (buf4));
+	nl = rtnl_route_get_dst (route);
+	if (nl) {
+		if (nl_addr_get_family (nl) == AF_INET) {
+			addr4 = nl_addr_get_binary_addr (nl);
+			if (addr4)
+				inet_ntop (AF_INET, addr4, &buf4[0], sizeof (buf4));
+		} else if (nl_addr_get_family (nl) == AF_INET6) {
+			addr6 = nl_addr_get_binary_addr (nl);
+			if (addr6)
+				inet_ntop (AF_INET6, addr6, &buf6[0], sizeof (buf6));
+		}
+		prefixlen = nl_addr_get_prefixlen (nl);
+	}
+
+	if (family == AF_INET) {
+		sf = "INET";
+		log_level = LOGD_IP4;
+	} else if (family == AF_INET6) {
+		sf = "INET6";
+		log_level = LOGD_IP6;
+	}
+
+	nm_log_dbg (log_level, "  route idx %d family %s (%d) addr %s/%d",
+	            rtnl_route_get_oif (route),
+	            sf, family,
+	            strlen (buf4) ? buf4 : (strlen (buf6) ? buf6 : "<unknown>"),
+	            prefixlen);
+}
+
+
+typedef struct {
+	int ifindex;
+	int family;
+	int scope;
+	gboolean ignore_inet6_ll_mc;
+	const char *iface;
+	NlRouteForeachFunc callback;
+	gpointer user_data;
+	struct rtnl_route *out_route;
+} ForeachRouteInfo;
+
+static void
+foreach_route_cb (struct nl_object *object, void *user_data)
+{
+	ForeachRouteInfo *info = user_data;
+	struct rtnl_route *route = (struct rtnl_route *) object;
+	struct nl_addr *dst;
+
+	if (info->out_route)
+		return;
+
+	if (nm_logging_level_enabled (LOGL_DEBUG))
+		dump_route (route);
+
+	if (   info->ifindex >= 0
+	    && rtnl_route_get_oif (route) != info->ifindex)
+		return;
+
+	if (   info->scope != RT_SCOPE_UNIVERSE
+	    && rtnl_route_get_scope (route) != info->scope)
+		return;
+
+	if (   info->family != AF_UNSPEC
+	    && rtnl_route_get_family (route) != info->family)
+		return;
+
+	dst = rtnl_route_get_dst (route);
+
+	/* Check for IPv6 LL and MC routes that might need to be ignored */
+	if (   (info->family == AF_INET6 || info->family == AF_UNSPEC)
+	    && (rtnl_route_get_family (route) == AF_INET6)) {
+		struct in6_addr *addr = NULL;
+
+		if (dst)
+			addr = nl_addr_get_binary_addr (dst);
+		if (addr) {
+			if (   IN6_IS_ADDR_LINKLOCAL (addr)
+			    || IN6_IS_ADDR_MC_LINKLOCAL (addr)
+			    || (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (dst) == 8)))
+				return;
+		}
+	}
+
+	info->out_route = info->callback (route, dst, info->iface, info->user_data);
+	if (info->out_route) {
+		/* Ref the route so it sticks around after the cache is cleared */
+		rtnl_route_get (info->out_route);
+	}
+}
+
+/**
+ * nm_netlink_foreach_route:
+ * @ifindex: the interface index to filter routes for
+ * @family: the address family to filter routes for
+ * @scope: route scope, eg RT_SCOPE_LINK
+ * @ignore_inet6_ll_mc: if %TRUE ignore IPv6 link-local and multi-cast routes
+ * @callback: function called when a route matches the filter
+ * @user_data: data passed to @callback
+ *
+ * Filters each route in the routing table against the given @ifindex and
+ * @family (if given) and calls @callback for each matching route.
+ *
+ * Returns: a route if @callback returned one; the caller must dispose of the
+ * route using rtnl_route_put() when it is no longer required.
+ **/
+struct rtnl_route *
+nm_netlink_foreach_route (int ifindex,
+                          int family,
+                          int scope,
+                          gboolean ignore_inet6_ll_mc,
+                          NlRouteForeachFunc callback,
+                          gpointer user_data)
+{
+	struct nl_cache *cache;
+	ForeachRouteInfo info;
+
+	memset (&info, 0, sizeof (info));
+	info.ifindex = ifindex;
+	info.family = family;
+	info.scope = scope;
+	info.ignore_inet6_ll_mc = ignore_inet6_ll_mc;
+	info.callback = callback;
+	info.user_data = user_data;
+	info.iface = nm_netlink_index_to_iface (ifindex);
+
+	rtnl_route_alloc_cache (nm_netlink_get_default_handle (), family, NL_AUTO_PROVIDE, &cache);
+	g_return_val_if_fail (cache != NULL, NULL);
+	nl_cache_foreach (cache, foreach_route_cb, &info);
+	nl_cache_free (cache);
+	return info.out_route;
+}
+
+
diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h
new file mode 100644
index 00000000..c6c452a0
--- /dev/null
+++ b/src/nm-netlink-utils.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_NETLINK_UTILS_H
+#define NM_NETLINK_UTILS_H
+
+#include <glib.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/route.h>
+
+gboolean nm_netlink_find_address (int ifindex,
+                                  int family,
+                                  void *addr,  /* struct in_addr or struct in6_addr */
+                                  int prefix_);
+
+typedef enum {
+	NMNL_PROP_INVALID = 0,
+	NMNL_PROP_PROT,
+	NMNL_PROP_SCOPE,
+	NMNL_PROP_TABLE,
+	NMNL_PROP_PRIO,
+} NmNlProp;
+
+struct rtnl_route * nm_netlink_route_new (int ifindex,
+                                          int family,
+                                          int mss,
+                                          ...) __attribute__((__sentinel__));
+
+int nm_netlink_route_add (struct rtnl_route *route,
+                          int family,
+                          const void * dst, /* struct in_addr or struct in6_addr */
+                          int prefix,
+                          const void * gw, /* struct in_addr or struct in6_addr */
+                          int flags);
+
+gboolean nm_netlink_route_delete (struct rtnl_route *route);
+
+/**
+ * NlRouteForeachFunc:
+ * @route: the route being processed
+ * @dst: the route's destination address
+ * @iface: the interface name of the index passed to nm_netlink_foreach_route()
+ * @in_family: the address family passed to nm_netlink_foreach_route()
+ * @user_data: the user data pointer passed to nm_netlink_foreach_route()
+ *
+ * Returns: a route to return to the caller of nm_netlink_foreach_route() which
+ * terminates routing table iteration, or NULL to continue iterating the
+ * routing table.
+ **/
+typedef struct rtnl_route * (*NlRouteForeachFunc) (struct rtnl_route *route,
+                                                   struct nl_addr *dst,
+                                                   const char *iface,
+                                                   gpointer user_data);
+
+struct rtnl_route * nm_netlink_foreach_route (int ifindex,
+                                              int family,
+                                              int scope,
+                                              gboolean ignore_inet6_ll_mc,
+                                              NlRouteForeachFunc callback,
+                                              gpointer user_data);
+
+#endif  /* NM_NETLINK_MONITOR_H */
+
diff --git a/src/nm-policy.c b/src/nm-policy.c
index a42a0fa9..02292f7a 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -425,6 +425,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	NMConnection *connection = NULL;
 	NMSettingConnection *s_con = NULL;
 	const char *connection_id;
+	int ip_ifindex = 0;
 
 	best = get_best_ip4_device (policy->manager, &best_req);
 	if (!best)
@@ -461,17 +462,18 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
 			NMDevice *parent;
 
 			ip_iface = nm_vpn_connection_get_ip_iface (candidate);
+			ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate);
 			connection = nm_vpn_connection_get_connection (candidate);
 			addr = nm_ip4_config_get_address (ip4_config, 0);
 
 			parent = nm_vpn_connection_get_parent_device (candidate);
 			parent_ip4 = nm_device_get_ip4_config (parent);
 
-			nm_system_replace_default_ip4_route_vpn (ip_iface,
+			nm_system_replace_default_ip4_route_vpn (ip_ifindex,
 			                                         nm_ip4_address_get_gateway (addr),
 			                                         nm_vpn_connection_get_ip4_internal_gateway (candidate),
 			                                         nm_ip4_config_get_mss (ip4_config),
-			                                         nm_device_get_ip_iface (parent),
+			                                         nm_device_get_ip_ifindex (parent),
 			                                         nm_ip4_config_get_mss (parent_ip4));
 
 			dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
@@ -483,12 +485,14 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	if (!ip_iface || !ip4_config) {
 		connection = nm_act_request_get_connection (best_req);
 		ip_iface = nm_device_get_ip_iface (best);
+		ip_ifindex = nm_device_get_ip_ifindex (best);
 		ip4_config = nm_device_get_ip4_config (best);
 		g_assert (ip4_config);
 		addr = nm_ip4_config_get_address (ip4_config, 0);
 
-		nm_system_replace_default_ip4_route (ip_iface, nm_ip4_address_get_gateway (addr), nm_ip4_config_get_mss (ip4_config));
-
+		nm_system_replace_default_ip4_route (ip_ifindex,
+		                                     nm_ip4_address_get_gateway (addr),
+		                                     nm_ip4_config_get_mss (ip4_config));
 		dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
 	}
 
@@ -551,6 +555,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	NMIP6Config *ip6_config = NULL;
 	NMIP6Address *addr;
 	const char *ip_iface = NULL;
+	int ip_ifindex = -1;
 	NMConnection *connection = NULL;
 	NMSettingConnection *s_con = NULL;
 	const char *connection_id;
@@ -608,11 +613,12 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	if (!ip_iface || !ip6_config) {
 		connection = nm_act_request_get_connection (best_req);
 		ip_iface = nm_device_get_ip_iface (best);
+		ip_ifindex = nm_device_get_ip_ifindex (best);
 		ip6_config = nm_device_get_ip6_config (best);
 		g_assert (ip6_config);
 		addr = nm_ip6_config_get_address (ip6_config, 0);
 
-		nm_system_replace_default_ip6_route (ip_iface, nm_ip6_address_get_gateway (addr));
+		nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_address_get_gateway (addr));
 
 		dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
 	}
diff --git a/src/nm-system.c b/src/nm-system.c
index 88db6596..0b294684 100644
--- a/src/nm-system.c
+++ b/src/nm-system.c
@@ -48,9 +48,8 @@
 #include "nm-utils.h"
 #include "nm-logging.h"
 #include "nm-netlink-monitor.h"
-
-/* Because of a bug in libnl, rtnl.h should be included before route.h */
-#include <netlink/route/rtnl.h>
+#include "nm-netlink-utils.h"
+#include "nm-netlink-compat.h"
 
 #include <netlink/route/addr.h>
 #include <netlink/route/route.h>
@@ -58,9 +57,9 @@
 #include <netlink/utils.h>
 #include <netlink/route/link.h>
 
-static void nm_system_device_set_priority (const char *iface,
-								   NMIP4Config *config,
-								   int priority);
+static void nm_system_device_set_priority (int ifindex,
+                                           NMIP4Config *config,
+                                           int priority);
 
 static gboolean
 ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix)
@@ -87,99 +86,54 @@ ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix)
 }
 
 static struct rtnl_route *
-create_route (int iface_idx, int mss)
-{
-	struct rtnl_route *route;
-
-	route = rtnl_route_alloc ();
-	if (route) {
-		rtnl_route_set_oif (route, iface_idx);
-
-		if (mss && rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0) {
-			nm_log_warn (LOGD_DEVICE, "could not set mss");
-		}
-	} else
-		nm_log_err (LOGD_DEVICE, "could not allocate route");
-
-	return route;
-}
-
-static struct rtnl_route *
-nm_system_device_set_ip4_route (const char *iface, 
+nm_system_device_set_ip4_route (int ifindex, 
                                 guint32 ip4_dest,
                                 guint32 ip4_prefix,
                                 guint32 ip4_gateway,
                                 guint32 metric,
                                 int mss)
 {
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct rtnl_route *route;
-	struct nl_addr *dest_addr;
-	struct nl_addr *gw_addr = NULL;
-	int err, iface_idx;
+	int err;
+	const char *iface;
+
+	g_return_val_if_fail (ifindex > 0, NULL);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, NULL);
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	g_return_val_if_fail (iface_idx >= 0, NULL);
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, NULL);
 
-	route = create_route (iface_idx, mss);
+	route = nm_netlink_route_new (ifindex, AF_INET, mss,
+	                              NMNL_PROP_PRIO, metric,
+	                              NULL);
 	g_return_val_if_fail (route != NULL, NULL);
 
-	/* Destination */
-	dest_addr = nl_addr_build (AF_INET, &ip4_dest, sizeof (ip4_dest));
-	g_return_val_if_fail (dest_addr != NULL, NULL);
-	nl_addr_set_prefixlen (dest_addr, (int) ip4_prefix);
-
-	rtnl_route_set_dst (route, dest_addr);
-	nl_addr_put (dest_addr);
-
-	/* Gateway */
-	if (ip4_gateway) {
-		gw_addr = nl_addr_build (AF_INET, &ip4_gateway, sizeof (ip4_gateway));
-		if (gw_addr) {
-			rtnl_route_set_gateway (route, gw_addr);
-			rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
-		} else {
-			nm_log_err (LOGD_DEVICE | LOGD_IP4, "Invalid gateway 0x%X", ip4_gateway);
-			rtnl_route_put (route);
-			return NULL;
-		}
-	}
-
-	/* Metric */
-	if (metric)
-		rtnl_route_set_prio (route, metric);
-
 	/* Add the route */
-	err = rtnl_route_add (nlh, route, 0);
-	if (err == -ESRCH && ip4_gateway) {
+	err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0);
+	if (err == -NLE_OBJ_NOTFOUND && ip4_gateway) {
 		/* Gateway might be over a bridge; try adding a route to gateway first */
 		struct rtnl_route *route2;
 
-		route2 = create_route (iface_idx, mss);
+		route2 = nm_netlink_route_new (ifindex, AF_INET, mss, NULL);
 		if (route2) {
 			/* Add route to gateway over bridge */
-			rtnl_route_set_dst (route2, gw_addr);
-			err = rtnl_route_add (nlh, route2, 0);
+			err = nm_netlink_route_add(route2, AF_INET, &ip4_gateway, 32, NULL, 0);
 			if (!err) {
-				/* Try adding the route again */
-				err = rtnl_route_add (nlh, route, 0);
+				err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0);
 				if (err)
-					rtnl_route_del (nlh, route2, 0);
+					nm_netlink_route_delete (route2);
 			}
 			rtnl_route_put (route2);
 		}
 	}
 
-	if (gw_addr)
-		nl_addr_put (gw_addr);
-
 	if (err) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to set IPv4 route: %s",
-		            iface, nl_geterror ());
+		            iface, nl_geterror (err));
 		rtnl_route_put (route);
 		route = NULL;
 	}
@@ -188,10 +142,12 @@ nm_system_device_set_ip4_route (const char *iface,
 }
 
 static gboolean
-sync_addresses (const char *iface, int ifindex, int family,
-				struct rtnl_addr **addrs, int num_addrs)
+sync_addresses (int ifindex,
+                int family,
+				struct rtnl_addr **addrs,
+				int num_addrs)
 {
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct nl_cache *addr_cache;
 	struct rtnl_addr *filter_addr, *match_addr;
 	struct nl_object *match;
@@ -199,6 +155,10 @@ sync_addresses (const char *iface, int ifindex, int family,
 	int i, err;
 	guint32 log_domain = (family == AF_INET) ? LOGD_IP4 : LOGD_IP6;
 	char buf[INET6_ADDRSTRLEN + 1];
+	const char *iface;
+
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
 	log_domain |= LOGD_DEVICE;
 
@@ -206,8 +166,8 @@ sync_addresses (const char *iface, int ifindex, int family,
 	if (!nlh)
 		return FALSE;
 
-	addr_cache = rtnl_addr_alloc_cache (nlh);
-	if (!addr_cache)
+	err = rtnl_addr_alloc_cache (nlh, &addr_cache);
+	if (err < 0)
 		return FALSE;
 
 	filter_addr = rtnl_addr_alloc ();
@@ -279,7 +239,7 @@ sync_addresses (const char *iface, int ifindex, int family,
 		err = rtnl_addr_delete (nlh, match_addr, 0);
 		if (err < 0) {
 			nm_log_err (log_domain, "(%s): error %d returned from rtnl_addr_delete(): %s",
-						iface, err, nl_geterror ());
+						iface, err, nl_geterror (err));
 		}
 	}
 
@@ -312,10 +272,10 @@ sync_addresses (const char *iface, int ifindex, int family,
 		}
 
 		err = rtnl_addr_add (nlh, addrs[i], 0);
-		if (err < 0 && (nl_get_errno () != EEXIST)) {
+		if (err < 0 && (err != -NLE_EXIST)) {
 			nm_log_err (log_domain,
 			            "(%s): error %d returned from rtnl_addr_add():\n%s",
-			            iface, err, nl_geterror ());
+			            iface, err, nl_geterror (err));
 		}
 
 		rtnl_addr_put (addrs[i]);
@@ -361,7 +321,7 @@ add_ip4_addresses (NMIP4Config *config, const char *iface)
 		rtnl_addr_set_ifindex (addrs[i], iface_idx);
 	}
 
-	return sync_addresses (iface, iface_idx, AF_INET, addrs, num_addrs);
+	return sync_addresses (iface_idx, AF_INET, addrs, num_addrs);
 }
 
 struct rtnl_route *
@@ -406,10 +366,10 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_c
 	 * parent device.
 	 */
 	if (ip4_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix)) {
-		route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
+		route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device),
 		                                        vpn_gw, 32, 0, 0, nm_ip4_config_get_mss (parent_config));
 	} else {
-		route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device),
+		route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device),
 		                                        vpn_gw, 32, parent_gw, 0, nm_ip4_config_get_mss (parent_config));
 	}
 
@@ -423,16 +383,20 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_c
  *
  */
 gboolean
-nm_system_apply_ip4_config (const char *iface,
+nm_system_apply_ip4_config (int ifindex,
                             NMIP4Config *config,
                             int priority,
                             NMIP4ConfigCompareFlags flags)
 {
+	const char *iface;
 	int i;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 	g_return_val_if_fail (config != NULL, FALSE);
 
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
+
 	if (flags & NM_IP4_COMPARE_FLAG_ADDRESSES) {
 		if (!add_ip4_addresses (config, iface))
 			return FALSE;
@@ -459,7 +423,7 @@ nm_system_apply_ip4_config (const char *iface,
 			    && nm_ip4_route_get_dest (route) == 0)
 				continue;
 
-			tmp = nm_system_device_set_ip4_route (iface,
+			tmp = nm_system_device_set_ip4_route (ifindex,
 			                                      nm_ip4_route_get_dest (route),
 			                                      nm_ip4_route_get_prefix (route),
 			                                      nm_ip4_route_get_next_hop (route),
@@ -471,11 +435,11 @@ nm_system_apply_ip4_config (const char *iface,
 
 	if (flags & NM_IP4_COMPARE_FLAG_MTU) {
 		if (nm_ip4_config_get_mtu (config))
-			nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
+			nm_system_iface_set_mtu (ifindex, nm_ip4_config_get_mtu (config));
 	}
 
 	if (priority > 0)
-		nm_system_device_set_priority (iface, config, priority);
+		nm_system_device_set_priority (ifindex, config, priority);
 
 	return TRUE;
 }
@@ -491,10 +455,8 @@ nm_system_set_ip6_route (int ifindex,
                          int table,
                          struct rtnl_route **out_route)
 {
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct rtnl_route *route;
-	struct nl_addr *dest_addr;
-	struct nl_addr *gw_addr = NULL;
 	int err = 0;
 
 	g_return_val_if_fail (ifindex >= 0, -1);
@@ -502,64 +464,33 @@ nm_system_set_ip6_route (int ifindex,
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, -1);
 
-	route = create_route (ifindex, mss);
+	route = nm_netlink_route_new (ifindex, AF_INET6, mss,
+	                              NMNL_PROP_PROT, protocol,
+	                              NMNL_PROP_PRIO, metric,
+	                              NMNL_PROP_TABLE, table,
+	                              NULL);
 	g_return_val_if_fail (route != NULL, -1);
 
-	/* Destination */
-	dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_dest, sizeof (*ip6_dest));
-	g_return_val_if_fail (dest_addr != NULL, -1);
-	nl_addr_set_prefixlen (dest_addr, (int) ip6_prefix);
-
-	rtnl_route_set_dst (route, dest_addr);
-	nl_addr_put (dest_addr);
-
-	/* Gateway */
-	if (ip6_gateway && !IN6_IS_ADDR_UNSPECIFIED (ip6_gateway)) {
-		gw_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_gateway, sizeof (*ip6_gateway));
-		if (gw_addr) {
-			rtnl_route_set_gateway (route, gw_addr);
-			rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
-		} else {
-			nm_log_warn (LOGD_DEVICE | LOGD_IP6, "Invalid gateway");
-			rtnl_route_put (route);
-			return -1;
-		}
-	}
-
-	/* Metric */
-	if (metric)
-		rtnl_route_set_prio (route, metric);
-
-	if (protocol)
-		rtnl_route_set_protocol (route, protocol);
-
-	if (table)
-		rtnl_route_set_table (route, table);
-
 	/* Add the route */
-	err = rtnl_route_add (nlh, route, 0);
-	if (err == -ESRCH && ip6_gateway) {
+	err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0);
+	if (err == -NLE_OBJ_NOTFOUND && ip6_gateway) {
 		/* Gateway might be over a bridge; try adding a route to gateway first */
 		struct rtnl_route *route2;
 
-		route2 = create_route (ifindex, mss);
+		route2 = nm_netlink_route_new (ifindex, AF_INET6, mss, NULL);
 		if (route2) {
+			err = nm_netlink_route_add(route, AF_INET6, &ip6_gateway, 128, NULL, 0);
 			/* Add route to gateway over bridge */
-			rtnl_route_set_dst (route2, gw_addr);
-			err = rtnl_route_add (nlh, route2, 0);
 			if (!err) {
 				/* Try adding the route again */
-				err = rtnl_route_add (nlh, route, 0);
+				err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0);
 				if (err)
-					rtnl_route_del (nlh, route2, 0);
+					nm_netlink_route_delete (route2);
 			}
 			rtnl_route_put (route2);
 		}
 	}
 
-	if (gw_addr)
-		nl_addr_put (gw_addr);
-
 	if (out_route)
 		*out_route = route;
 	else
@@ -595,7 +526,7 @@ add_ip6_addresses (NMIP6Config *config, const char *iface)
 		rtnl_addr_set_ifindex (addrs[i], iface_idx);
 	}
 
-	return sync_addresses (iface, iface_idx, AF_INET6, addrs, num_addrs);
+	return sync_addresses (iface_idx, AF_INET6, addrs, num_addrs);
 }
 
 /*
@@ -605,16 +536,20 @@ add_ip6_addresses (NMIP6Config *config, const char *iface)
  *
  */
 gboolean
-nm_system_apply_ip6_config (const char *iface,
+nm_system_apply_ip6_config (int ifindex,
                             NMIP6Config *config,
                             int priority,
                             NMIP6ConfigCompareFlags flags)
 {
+	const char *iface;
 	int i;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 	g_return_val_if_fail (config != NULL, FALSE);
 
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
+
 	if (flags & NM_IP6_COMPARE_FLAG_ADDRESSES) {
 		if (!add_ip6_addresses (config, iface))
 			return FALSE;
@@ -622,8 +557,6 @@ nm_system_apply_ip6_config (const char *iface,
 	}
 
 	if (flags & NM_IP6_COMPARE_FLAG_ROUTES) {
-		int ifindex = nm_netlink_iface_to_index (iface);
-
 		for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) {
 			NMIP6Route *route = nm_ip6_config_get_route (config, i);
 			int err;
@@ -647,7 +580,7 @@ nm_system_apply_ip6_config (const char *iface,
 			if (err) {
 				nm_log_err (LOGD_DEVICE | LOGD_IP6,
 				            "(%s): failed to set IPv6 route: %s",
-				            iface, nl_geterror ());
+				            iface, nl_geterror (err));
 			}
 		}
 	}
@@ -659,166 +592,182 @@ nm_system_apply_ip6_config (const char *iface,
 	return TRUE;
 }
 
-/*
- * nm_system_device_set_up_down
+/**
+ * nm_system_iface_set_up:
+ * @ifindex: interface index
+ * @up: %TRUE to bring interface up, or %FALSE to take it down
+ * @no_firmware: on return, %TRUE if the operation may have failed due to
+ * missing firmware
  *
- * Mark the device as up or down.
+ * Bring the interface up or take it down.
  *
- */
+ * Returns: %TRUE on success, %FALSE on failure
+ **/
 gboolean
-nm_system_device_set_up_down (NMDevice *dev,
-                              gboolean up,
-                              gboolean *no_firmware)
-{
-	g_return_val_if_fail (dev != NULL, FALSE);
-
-	return nm_system_device_set_up_down_with_iface (nm_device_get_ip_iface (dev), up, no_firmware);
-}
-
-gboolean
-nm_system_device_set_up_down_with_iface (const char *iface,
-                                         gboolean up,
-                                         gboolean *no_firmware)
+nm_system_iface_set_up (int ifindex,
+                        gboolean up,
+                        gboolean *no_firmware)
 {
 	struct rtnl_link *request = NULL, *old = NULL;
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	gboolean success = FALSE;
-	guint32 idx;
+	int err;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 	if (no_firmware)
 		g_return_val_if_fail (*no_firmware == FALSE, FALSE);
 
 	if (!(request = rtnl_link_alloc ()))
-		goto out;
+		return FALSE;
 
 	if (up)
 		rtnl_link_set_flags (request, IFF_UP);
 	else
 		rtnl_link_unset_flags (request, IFF_UP);
 
-	idx = nm_netlink_iface_to_index (iface);
-	old = nm_netlink_index_to_rtnl_link (idx);
+	old = nm_netlink_index_to_rtnl_link (ifindex);
 	if (old) {
 		nlh = nm_netlink_get_default_handle ();
 		if (nlh) {
-			if (rtnl_link_change (nlh, old, request, 0) == 0)
+			err = rtnl_link_change (nlh, old, request, 0);
+			if (err == 0) {
 				success = TRUE;
-			else if ((nl_get_errno () == ENOENT) && no_firmware && up)
-				*no_firmware = TRUE;
+			} else {
+				if ((err == -NLE_OBJ_NOTFOUND) && no_firmware && up)
+					*no_firmware = TRUE;
+			}
 		}
 	}
 
 	rtnl_link_put (old);
 	rtnl_link_put (request);
-
-out:
 	return success;
 }
 
+/**
+ * nm_system_iface_is_up:
+ * @ifindex: interface index
+ *
+ * Returns: %TRUE if the interface is up, %FALSE if it was down or the check
+ * failed.
+ **/
 gboolean
-nm_system_device_is_up (NMDevice *device)
+nm_system_iface_is_up (int ifindex)
 {
-	g_return_val_if_fail (device != NULL, FALSE);
+	const char *iface;
+	struct rtnl_link *l;
+	guint32 flags;
 
-	return nm_system_device_is_up_with_iface (nm_device_get_ip_iface (device));
-}
+	g_return_val_if_fail (ifindex > 0, FALSE);
 
-gboolean
-nm_system_device_is_up_with_iface (const char *iface)
-{
-	struct ifreq ifr;
-	int fd;
-	gboolean up = FALSE;
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
-	fd = socket (PF_INET, SOCK_DGRAM, 0);
-	if (fd < 0) {
-		nm_log_err (LOGD_HW, "couldn't open control socket.");
+	l = nm_netlink_index_to_rtnl_link (ifindex);
+	if (l == NULL) {
+		nm_log_err (LOGD_HW, "(%s): failed to get interface link object", iface);
 		return FALSE;
 	}
 
-	/* Get device's flags */
-	memset (&ifr, 0, sizeof (ifr));
-	strncpy (ifr.ifr_name, iface, IFNAMSIZ);
-	if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0) {
-		if (errno != ENODEV) {
-			nm_log_err (LOGD_HW, "(%s): could not get flags: errno %d",
-			            iface, errno);
-		}
-	} else {
-		up = !!(ifr.ifr_flags & IFF_UP);
-	}
-	close (fd);
+	flags = rtnl_link_get_flags (l);
+	rtnl_link_put (l);
 
-	return up;
+	return flags & IFF_UP;
 }
 
+/**
+ * nm_system_iface_set_mtu:
+ * @ifindex: interface index
+ * @mtu: the new MTU
+ *
+ * Returns: %TRUE if the request was successful, %FALSE if it failed
+ **/
 gboolean
-nm_system_device_set_mtu (const char *iface, guint32 mtu)
+nm_system_iface_set_mtu (int ifindex, guint32 mtu)
 {
 	struct rtnl_link *old;
 	struct rtnl_link *new;
 	gboolean success = FALSE;
-	struct nl_handle *nlh;
-	int iface_idx;
+	struct nl_sock *nlh;
+	const char *iface;
+	int err;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 	g_return_val_if_fail (mtu > 0, FALSE);
 
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
+
 	new = rtnl_link_alloc ();
 	if (!new)
 		return FALSE;
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	old = nm_netlink_index_to_rtnl_link (iface_idx);
+	old = nm_netlink_index_to_rtnl_link (ifindex);
 	if (old) {
 		rtnl_link_set_mtu (new, mtu);
 		nlh = nm_netlink_get_default_handle ();
 		if (nlh) {
-			rtnl_link_change (nlh, old, new, 0);
-			success = TRUE;
+			err = rtnl_link_change (nlh, old, new, 0);
+			if (err == 0)
+				success = TRUE;
+			else
+				nm_log_warn (LOGD_HW, "(%s): failed to change interface MTU", iface);
 		}
 		rtnl_link_put (old);
 	}
-
 	rtnl_link_put (new);
+
 	return success;
 }
 
+/**
+ * nm_system_iface_set_mac:
+ * @ifindex: interface index
+ * @mac: new MAC address
+ *
+ * Attempts to change the interface's MAC address to the requested value,
+ * ie MAC spoofing or cloning.
+ *
+ * Returns: %TRUE if the request succeeded, %FALSE if it failed.
+ **/
 gboolean
-nm_system_device_set_mac (const char *iface, const struct ether_addr *mac)
+nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac)
 {
-	struct rtnl_link *old;
-	struct rtnl_link *new;
+	struct rtnl_link *old, *new;
 	gboolean success = FALSE;
-	struct nl_handle *nlh;
-	int iface_idx;
+	struct nl_sock *nlh;
+	const char *iface;
 	struct nl_addr *addr = NULL;
+	int err;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 	g_return_val_if_fail (mac != NULL, FALSE);
 
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
+
 	new = rtnl_link_alloc ();
 	if (!new)
 		return FALSE;
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	old = nm_netlink_index_to_rtnl_link (iface_idx);
+	old = nm_netlink_index_to_rtnl_link (ifindex);
 	if (old) {
 		addr = nl_addr_build (AF_LLC, (void *) mac, ETH_ALEN);
 		if (!addr) {
-			char *mac_str;
-			mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->ether_addr_octet[0], mac->ether_addr_octet[1], mac->ether_addr_octet[2],
-			                                                            mac->ether_addr_octet[3], mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
-			nm_log_err (LOGD_DEVICE, "(%s): could not allocate memory for MAC address (%s)", iface, mac_str);
-			g_free (mac_str);
+			nm_log_err (LOGD_HW, "(%s): failed to allocate memory for MAC address change", iface);
+			rtnl_link_put (old);
+			rtnl_link_put (new);
 			return FALSE;
 		}
 		rtnl_link_set_addr (new, addr);
+		nl_addr_put (addr);
 		nlh = nm_netlink_get_default_handle ();
 		if (nlh) {
-			rtnl_link_change (nlh, old, new, 0);
-			success = TRUE;
+			err = rtnl_link_change (nlh, old, new, 0);
+			if (err == 0)
+				success = TRUE;
+			else
+				nm_log_warn (LOGD_HW, "(%s): failed to change interface MAC address", iface);
 		}
 		rtnl_link_put (old);
 	}
@@ -828,44 +777,28 @@ nm_system_device_set_mac (const char *iface, const struct ether_addr *mac)
 }
 
 static struct rtnl_route *
-add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss)
+add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss)
 {
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct rtnl_route *route = NULL;
-	struct nl_addr *gw_addr = NULL;
-	int iface_idx, err;
+	const char *iface;
+	int err;
+
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, NULL);
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	if (iface_idx < 0)
-		return NULL;
-
 	/* Gateway might be over a bridge; try adding a route to gateway first */
-	route = rtnl_route_alloc ();
-	if (route == NULL)
-		return NULL;
-
-	rtnl_route_set_family (route, AF_INET);
-	rtnl_route_set_table (route, RT_TABLE_MAIN);
-	rtnl_route_set_oif (route, iface_idx);
-	rtnl_route_set_scope (route, RT_SCOPE_LINK);
-
-	gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw));
-	if (!gw_addr)
-		goto error;
-	nl_addr_set_prefixlen (gw_addr, 32);
-	rtnl_route_set_dst (route, gw_addr);
-	nl_addr_put (gw_addr);
-
-	if (mss) {
-		if (rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0)
-			goto error;
-	}
+	route = nm_netlink_route_new (ifindex, AF_INET, mss,
+	                              NMNL_PROP_SCOPE, RT_SCOPE_LINK,
+	                              NMNL_PROP_TABLE, RT_TABLE_MAIN,
+	                              NULL);
+	g_return_val_if_fail (route != NULL, NULL);
 
 	/* Add direct route to the gateway */
-	err = rtnl_route_add (nlh, route, 0);
+	err = nm_netlink_route_add(route, AF_INET, &gw, 32, NULL, 0);
 	if (err) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to add IPv4 route to gateway (%d)",
@@ -881,64 +814,27 @@ error:
 }
 
 static int
-replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
+replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss)
 {
 	struct rtnl_route *route = NULL;
-	struct nl_handle *nlh;
-	struct nl_addr *dst_addr = NULL;
-	guint32 dst = 0;
-	struct nl_addr *gw_addr = NULL;
-	int iface_idx, err = -1;
+	struct nl_sock *nlh;
+	int err = -1;
+	int dst=0;
 
-	g_return_val_if_fail (iface != NULL, -ENODEV);
+	g_return_val_if_fail (ifindex > 0, -ENODEV);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, -ENOMEM);
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	if (iface_idx < 0)
-		return -ENODEV;
-
-	route = rtnl_route_alloc();
+	route = nm_netlink_route_new (ifindex, AF_INET, mss,
+	                              NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE,
+	                              NMNL_PROP_TABLE, RT_TABLE_MAIN,
+	                              NULL);
 	g_return_val_if_fail (route != NULL, -ENOMEM);
 
-	rtnl_route_set_family (route, AF_INET);
-	rtnl_route_set_table (route, RT_TABLE_MAIN);
-	rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
-	rtnl_route_set_oif (route, iface_idx);
-
-	/* Build up the destination address */
-	dst_addr = nl_addr_build (AF_INET, &dst, sizeof (dst));
-	if (!dst_addr) {
-		err = -ENOMEM;
-		goto out;
-	}
-	nl_addr_set_prefixlen (dst_addr, 0);
-	rtnl_route_set_dst (route, dst_addr);
-
-	/* Build up the gateway address */
-	gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw));
-	if (!gw_addr) {
-		err = -ENOMEM;
-		goto out;
-	}
-	nl_addr_set_prefixlen (gw_addr, 0);
-	rtnl_route_set_gateway (route, gw_addr);
-
-	if (mss > 0) {
-		err = rtnl_route_set_metric (route, RTAX_ADVMSS, mss);
-		if (err < 0)
-			goto out;
-	}
-
 	/* Add the new default route */
-	err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
+	err = nm_netlink_route_add (route, AF_INET, &dst, 0, &gw, NLM_F_REPLACE);
 
-out:
-	if (dst_addr)
-		nl_addr_put (dst_addr);
-	if (gw_addr)
-		nl_addr_put (gw_addr);
 	rtnl_route_put (route);
 	return err;
 }
@@ -950,25 +846,29 @@ out:
  *
  */
 gboolean
-nm_system_replace_default_ip4_route_vpn (const char *iface,
+nm_system_replace_default_ip4_route_vpn (int ifindex,
                                          guint32 ext_gw,
                                          guint32 int_gw,
                                          guint32 mss,
-                                         const char *parent_iface,
+                                         int parent_ifindex,
                                          guint32 parent_mss)
 {
 	struct rtnl_route *gw_route = NULL;
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	gboolean success = FALSE;
 	int err;
+	const char *iface;
+
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, FALSE);
 
-	err = replace_default_ip4_route (iface, int_gw, mss);
+	err = replace_default_ip4_route (ifindex, int_gw, mss);
 	if (err == 0) {
 		return TRUE;
-	} else if (err != -ESRCH) {
+	} else if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to set IPv4 default route: %d",
 		            iface, err);
@@ -976,14 +876,14 @@ nm_system_replace_default_ip4_route_vpn (const char *iface,
 	}
 
 	/* Try adding a direct route to the gateway first */
-	gw_route = add_ip4_route_to_gateway (parent_iface, ext_gw, parent_mss);
+	gw_route = add_ip4_route_to_gateway (parent_ifindex, ext_gw, parent_mss);
 	if (!gw_route)
 		return FALSE;
 
 	/* Try adding the original route again */
-	err = replace_default_ip4_route (iface, int_gw, mss);
+	err = replace_default_ip4_route (ifindex, int_gw, mss);
 	if (err != 0) {
-		rtnl_route_del (nlh, gw_route, 0);
+		nm_netlink_route_delete (gw_route);
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to set IPv4 default route (pass #2): %d",
 		            iface, err);
@@ -1001,20 +901,20 @@ nm_system_replace_default_ip4_route_vpn (const char *iface,
  *
  */
 gboolean
-nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
+nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss)
 {
 	struct rtnl_route *gw_route = NULL;
-	struct nl_handle *nlh;
 	gboolean success = FALSE;
+	const char *iface;
 	int err;
 
-	nlh = nm_netlink_get_default_handle ();
-	g_return_val_if_fail (nlh != NULL, FALSE);
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
-	err = replace_default_ip4_route (iface, gw, mss);
+	err = replace_default_ip4_route (ifindex, gw, mss);
 	if (err == 0) {
 		return TRUE;
-	} else if (err != -ESRCH) {
+	} else if (err != -NLE_OBJ_NOTFOUND) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to set IPv4 default route: %d",
 		            iface, err);
@@ -1022,14 +922,14 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
 	}
 
 	/* Try adding a direct route to the gateway first */
-	gw_route = add_ip4_route_to_gateway (iface, gw, mss);
+	gw_route = add_ip4_route_to_gateway (ifindex, gw, mss);
 	if (!gw_route)
 		return FALSE;
 
 	/* Try adding the original route again */
-	err = replace_default_ip4_route (iface, gw, mss);
+	err = replace_default_ip4_route (ifindex, gw, mss);
 	if (err != 0) {
-		rtnl_route_del (nlh, gw_route, 0);
+		nm_netlink_route_delete (gw_route);
 		nm_log_err (LOGD_DEVICE | LOGD_IP4,
 		            "(%s): failed to set IPv4 default route (pass #2): %d",
 		            iface, err);
@@ -1041,39 +941,28 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
 }
 
 static struct rtnl_route *
-add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw)
+add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw)
 {
-	struct nl_handle *nlh;
+	struct nl_sock *nlh;
 	struct rtnl_route *route = NULL;
-	struct nl_addr *gw_addr = NULL;
-	int iface_idx, err;
+	const char *iface;
+	int err;
+
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, NULL);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, NULL);
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	if (iface_idx < 0)
-		return NULL;
-
 	/* Gateway might be over a bridge; try adding a route to gateway first */
-	route = rtnl_route_alloc ();
-	if (route == NULL)
-		return NULL;
-
-	rtnl_route_set_family (route, AF_INET6);
-	rtnl_route_set_table (route, RT_TABLE_MAIN);
-	rtnl_route_set_oif (route, iface_idx);
-	rtnl_route_set_scope (route, RT_SCOPE_LINK);
-
-	gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw));
-	if (!gw_addr)
-		goto error;
-	nl_addr_set_prefixlen (gw_addr, 128);
-	rtnl_route_set_dst (route, gw_addr);
-	nl_addr_put (gw_addr);
+	route = nm_netlink_route_new (ifindex, AF_INET6, 0,
+	                              NMNL_PROP_SCOPE, RT_SCOPE_LINK,
+	                              NMNL_PROP_TABLE, RT_TABLE_MAIN,
+	                              NULL);
+	g_return_val_if_fail (route != NULL, NULL);
 
 	/* Add direct route to the gateway */
-	err = rtnl_route_add (nlh, route, 0);
+	err = nm_netlink_route_add(route, AF_INET, gw, 128, NULL, 0);
 	if (err) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP6,
 		            "(%s): failed to add IPv4 route to gateway (%d)",
@@ -1089,44 +978,30 @@ error:
 }
 
 static int
-replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
+replace_default_ip6_route (int ifindex, const struct in6_addr *gw)
 {
 	struct rtnl_route *route = NULL;
-	struct nl_handle *nlh;
-	struct nl_addr *gw_addr = NULL;
-	int iface_idx, err = -1;
+	struct nl_sock *nlh;
+	const char *iface;
+	int err = -1;
 
-	g_return_val_if_fail (iface != NULL, -ENODEV);
+	g_return_val_if_fail (ifindex > 0, FALSE);
+
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
 	nlh = nm_netlink_get_default_handle ();
 	g_return_val_if_fail (nlh != NULL, -ENOMEM);
 
-	iface_idx = nm_netlink_iface_to_index (iface);
-	if (iface_idx < 0)
-		return -ENODEV;
-
-	route = rtnl_route_alloc();
+	route = nm_netlink_route_new (ifindex, AF_INET6, 0,
+	                              NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE,
+	                              NMNL_PROP_TABLE, RT_TABLE_MAIN,
+	                              NULL);
 	g_return_val_if_fail (route != NULL, -ENOMEM);
 
-	rtnl_route_set_family (route, AF_INET6);
-	rtnl_route_set_table (route, RT_TABLE_MAIN);
-	rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
-	rtnl_route_set_oif (route, iface_idx);
-
-	if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) {
-		/* Build up the gateway address */
-		gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw));
-		if (!gw_addr) {
-			err = -ENOMEM;
-			goto out;
-		}
-		nl_addr_set_prefixlen (gw_addr, -1);
-		rtnl_route_set_gateway (route, gw_addr);
-	}
-
 	/* Add the new default route */
-	err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
-	if (err == -EEXIST) {
+	nm_netlink_route_add(route, AF_INET6, NULL, 0, gw, NLM_F_REPLACE);
+	if (err == -NLE_EXIST) {
 		/* FIXME: even though we use NLM_F_REPLACE the kernel won't replace
 		 * the route if it's the same.  Should try to remove it first, then
 		 * add the new one again here.
@@ -1134,9 +1009,6 @@ replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
 		err = 0;
 	}
 
-out:
-	if (gw_addr)
-		nl_addr_put (gw_addr);
 	rtnl_route_put (route);
 	return err;
 }
@@ -1148,20 +1020,20 @@ out:
  *
  */
 gboolean
-nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
+nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw)
 {
 	struct rtnl_route *gw_route = NULL;
-	struct nl_handle *nlh;
 	gboolean success = FALSE;
+	const char *iface;
 	int err;
 
-	nlh = nm_netlink_get_default_handle ();
-	g_return_val_if_fail (nlh != NULL, FALSE);
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
-	err = replace_default_ip6_route (iface, gw);
-	if (err == 0) {
+	err = replace_default_ip6_route (ifindex, gw);
+	if (err == 0)
 		return TRUE;
-	} else if (err != -ESRCH) {
+	if (err != -NLE_OBJ_NOTFOUND) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP6,
 		            "(%s): failed to set IPv6 default route: %d",
 		            iface, err);
@@ -1169,14 +1041,14 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g
 	}
 
 	/* Try adding a direct route to the gateway first */
-	gw_route = add_ip6_route_to_gateway (iface, gw);
+	gw_route = add_ip6_route_to_gateway (ifindex, gw);
 	if (!gw_route)
 		return FALSE;
 
 	/* Try adding the original route again */
-	err = replace_default_ip6_route (iface, gw);
+	err = replace_default_ip6_route (ifindex, gw);
 	if (err != 0) {
-		rtnl_route_del (nlh, gw_route, 0);
+		nm_netlink_route_delete (gw_route);
 		nm_log_err (LOGD_DEVICE | LOGD_IP6,
 		            "(%s): failed to set IPv6 default route (pass #2): %d",
 		            iface, err);
@@ -1187,169 +1059,55 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g
 	return success;
 }
 
-static void flush_addresses (const char *iface, int family)
-{
-	int iface_idx;
-
-	g_return_if_fail (iface != NULL);
-	iface_idx = nm_netlink_iface_to_index (iface);
-	if (iface_idx >= 0)
-		sync_addresses (iface, iface_idx, family, NULL, 0);
-}
-
-/*
- * nm_system_device_flush_addresses
- *
- * Flush all network addresses associated with a network device
- *
- */
-void nm_system_device_flush_addresses (NMDevice *dev, int family)
-{
-	g_return_if_fail (dev != NULL);
-
-	flush_addresses (nm_device_get_ip_iface (dev), family);
-}
-
-
 /*
- * nm_system_device_flush_addresses_with_iface
+ * nm_system_iface_flush_addresses
  *
  * Flush all network addresses associated with a network device
  *
  */
-void nm_system_device_flush_addresses_with_iface (const char *iface)
-{
-	flush_addresses (iface, AF_UNSPEC);
-}
-
-
-static void
-foreach_route (void (*callback)(struct nl_object *, gpointer),
-			gpointer user_data)
-{
-	struct nl_handle *nlh;
-	struct nl_cache *route_cache;
-
-	nlh = nm_netlink_get_default_handle ();
-	route_cache = rtnl_route_alloc_cache (nlh);
-	g_assert (route_cache);
-	nl_cache_foreach (route_cache, callback, user_data);
-	nl_cache_free (route_cache);
-}
-
-static void
-dump_route (struct rtnl_route *route)
+gboolean
+nm_system_iface_flush_addresses (int ifindex, int family)
 {
-	char buf6[INET6_ADDRSTRLEN];
-	char buf4[INET_ADDRSTRLEN];
-	struct nl_addr *nl;
-	struct in6_addr *addr6 = NULL;
-	struct in_addr *addr4 = NULL;
-	int prefixlen = 0;
-	const char *sf = "UNSPEC";
-	int family = rtnl_route_get_family (route);
-
-	memset (buf6, 0, sizeof (buf6));
-	memset (buf4, 0, sizeof (buf4));
-	nl = rtnl_route_get_dst (route);
-	if (nl) {
-		if (nl_addr_get_family (nl) == AF_INET) {
-			addr4 = nl_addr_get_binary_addr (nl);
-			if (addr4)
-				inet_ntop (AF_INET, addr4, &buf4[0], sizeof (buf4));
-		} else if (nl_addr_get_family (nl) == AF_INET6) {
-			addr6 = nl_addr_get_binary_addr (nl);
-			if (addr6)
-				inet_ntop (AF_INET6, addr6, &buf6[0], sizeof (buf6));
-		}
-		prefixlen = nl_addr_get_prefixlen (nl);
-	}
-
-	if (family == AF_INET)
-		sf = "INET";
-	else if (family == AF_INET6)
-		sf = "INET6";
-
-	nm_log_dbg (LOGD_IP4 | LOGD_IP6, "  route idx %d family %s (%d) addr %s/%d",
-	            rtnl_route_get_oif (route),
-	            sf, family,
-	            strlen (buf4) ? buf4 : (strlen (buf6) ? buf6 : "<unknown>"),
-	            prefixlen);
+	g_return_val_if_fail (ifindex > 0, FALSE);
+	return sync_addresses (ifindex, family, NULL, 0);
 }
 
-typedef struct {
-	const char *iface;
-	int iface_idx;
-	int family;
-} RouteCheckData;
 
-static void
-check_one_route (struct nl_object *object, void *user_data)
+static struct rtnl_route *
+delete_one_route (struct rtnl_route *route,
+                  struct nl_addr *dst,
+                  const char *iface,
+                  gpointer user_data)
 {
-	RouteCheckData *data = (RouteCheckData *) user_data;
-	struct rtnl_route *route = (struct rtnl_route *) object;
-	int err;
-	guint32 log_level = LOGD_IP4 | LOGD_IP6;
-
-	if (nm_logging_level_enabled (LOGL_DEBUG))
-		dump_route (route);
+	guint32 log_level = GPOINTER_TO_UINT (user_data);
 
-	/* Delete all routes from this interface */
-	if (rtnl_route_get_oif (route) != data->iface_idx)
-		return;
-	if (data->family && rtnl_route_get_family (route) != data->family)
-		return;
-
-	/* We don't want to flush IPv6 link-local routes that may exist on the
-	 * the interface since the LL address and routes should normally stay
-	 * assigned all the time.
-	 */
-	if (   (data->family == AF_INET6 || data->family == AF_UNSPEC)
-	    && (rtnl_route_get_family (route) == AF_INET6)) {
-		struct nl_addr *nl;
-		struct in6_addr *addr = NULL;
-
-		nl = rtnl_route_get_dst (route);
-		if (nl)
-			addr = nl_addr_get_binary_addr (nl);
-
-		if (addr) {
-			if (   IN6_IS_ADDR_LINKLOCAL (addr)
-			    || IN6_IS_ADDR_MC_LINKLOCAL (addr)
-			    || (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (nl) == 8)))
-				return;
-		}
-	}
-
-	if (data->family == AF_INET)
-		log_level = LOGD_IP4;
-	else if (data->family == AF_INET6)
-		log_level = LOGD_IP6;
 	nm_log_dbg (log_level, "   deleting route");
+	if (!nm_netlink_route_delete (route))
+		nm_log_err (LOGD_DEVICE, "(%s): failed to delete route", iface);
 
-	err = rtnl_route_del (nm_netlink_get_default_handle (), route, 0);
-	if (err < 0 && (err != -ERANGE)) {
-		nm_log_err (LOGD_DEVICE,
-		            "(%s): error %d returned from rtnl_route_del(): %s",
-		            data->iface, err, nl_geterror ());
-	}
+	return NULL;
 }
 
-static void flush_routes (int ifindex, const char *iface, int family)
+/**
+ * nm_system_iface_flush_routes:
+ * @ifindex: interface index
+ * @family: address family, i.e. AF_INET, AF_INET6, or AF_UNSPEC
+ *
+ * Flush all network addresses associated with a network device.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ **/
+gboolean
+nm_system_iface_flush_routes (int ifindex, int family)
 {
-	RouteCheckData check_data;
 	guint32 log_level = LOGD_IP4 | LOGD_IP6;
 	const char *sf = "UNSPEC";
+	const char *iface;
 
-	g_return_if_fail (iface != NULL);
+	g_return_val_if_fail (ifindex > 0, FALSE);
 
-	if (ifindex < 0) {
-		ifindex = nm_netlink_iface_to_index (iface);
-		if (ifindex < 0) {
-			nm_log_dbg (LOGD_DEVICE, "(%s) failed to lookup interface index", iface);
-			return;
-		}
-	}
+	iface = nm_netlink_index_to_iface (ifindex);
+	g_return_val_if_fail (iface != NULL, FALSE);
 
 	if (family == AF_INET) {
 		log_level = LOGD_IP4;
@@ -1361,104 +1119,59 @@ static void flush_routes (int ifindex, const char *iface, int family)
 	nm_log_dbg (log_level, "(%s): flushing routes ifindex %d family %s (%d)",
 	            iface, ifindex, sf, family);
 
-	memset (&check_data, 0, sizeof (check_data));
-	check_data.iface = iface;
-	check_data.iface_idx = ifindex;
-	check_data.family = family;
-	foreach_route (check_one_route, &check_data);
-}
-
-/*
- * nm_system_device_flush_routes
- *
- * Flush all network addresses associated with a network device
- *
- */
-void nm_system_device_flush_routes (NMDevice *dev, int family)
-{
-	g_return_if_fail (dev != NULL);
-
-	flush_routes (nm_device_get_ip_ifindex (dev),
-	              nm_device_get_ip_iface (dev),
-	              family);
-}
-
-/*
- * nm_system_device_flush_routes_with_iface
- *
- * Flush all routes associated with a network device.  'family' is an
- * address family, either AF_INET, AF_INET6, or AF_UNSPEC.
- *
- */
-void nm_system_device_flush_routes_with_iface (const char *iface, int family)
-{
-	flush_routes (-1, iface, family);
+	/* We don't want to flush IPv6 link-local routes that may exist on the
+	 * the interface since the LL address and routes should normally stay
+	 * assigned all the time.
+	 */
+	nm_netlink_foreach_route (ifindex, family, RT_SCOPE_UNIVERSE, TRUE, delete_one_route, GUINT_TO_POINTER (log_level));
+	return TRUE;
 }
 
-typedef struct {
-	struct rtnl_route *route;
-	NMIP4Config *config;
-	int iface;
-} SetPriorityInfo;
-
-static void
-find_route (struct nl_object *object, gpointer user_data)
+static struct rtnl_route *
+find_route (struct rtnl_route *route,
+            struct nl_addr *dst,
+            const char *iface,
+            gpointer user_data)
 {
-	struct rtnl_route *route = (struct rtnl_route *) object;
-	SetPriorityInfo *info = (SetPriorityInfo *) user_data;
-	struct nl_addr *dst;
+	NMIP4Config *config = user_data;
 	struct in_addr *dst_addr;
 	int num;
 	int i;
 
-	if (info->route ||
-	    rtnl_route_get_oif (route) != info->iface ||
-	    rtnl_route_get_scope (route) != RT_SCOPE_LINK)
-		return;
-
-	dst = rtnl_route_get_dst (route);
-	if (nl_addr_get_family (dst) != AF_INET)
-		return;
+	if (dst && (nl_addr_get_family (dst) != AF_INET))
+		return NULL;
 
+	/* Find the first route that handles a subnet of at least one of the
+	 * device's IPv4 addresses.
+	 */
 	dst_addr = nl_addr_get_binary_addr (dst);
-	num = nm_ip4_config_get_num_addresses (info->config);
+	num = nm_ip4_config_get_num_addresses (config);
 	for (i = 0; i < num; i++) {
-		NMIP4Address *addr = nm_ip4_config_get_address (info->config, i);
+		NMIP4Address *addr = nm_ip4_config_get_address (config, i);
 		guint32 prefix = nm_ip4_address_get_prefix (addr);
 		guint32 address = nm_ip4_address_get_address (addr);
 
-		if (prefix == nl_addr_get_prefixlen (dst) &&
-		    (address & nm_utils_ip4_prefix_to_netmask (prefix)) == dst_addr->s_addr) {
-
-			/* Ref the route so it sticks around after the cache is cleared */
-			rtnl_route_get (route);
-			info->route = route;
-			break;
-		}
+		if (   prefix == nl_addr_get_prefixlen (dst)
+		    && (address & nm_utils_ip4_prefix_to_netmask (prefix)) == dst_addr->s_addr)
+			return route;
 	}
+	return NULL;
 }
 
 static void
-nm_system_device_set_priority (const char *iface,
-						 NMIP4Config *config,
-						 int priority)
+nm_system_device_set_priority (int ifindex,
+                               NMIP4Config *config,
+                               int priority)
 {
-	SetPriorityInfo info;
-
-	info.route = NULL;
-	info.config = config;
-	info.iface = nm_netlink_iface_to_index (iface);
-	g_return_if_fail (info.iface >= 0);
-
-	foreach_route (find_route, &info);
-	if (info.route) {
-		struct nl_handle *nlh;
+	struct nl_sock *nlh;
+	struct rtnl_route *found;
 
+	found = nm_netlink_foreach_route (ifindex, AF_INET, RT_SCOPE_LINK, FALSE,  find_route, config);
+	if (found) {
 		nlh = nm_netlink_get_default_handle ();
-		rtnl_route_del (nlh, info.route, 0);
-
-		rtnl_route_set_prio (info.route, priority);
-		rtnl_route_add (nlh, info.route, 0);
-		rtnl_route_put (info.route);
+		nm_netlink_route_delete (found);
+		rtnl_route_set_priority (found, priority);
+		rtnl_route_add (nlh, found, 0);
+		rtnl_route_put (found);
 	}
 }
diff --git a/src/nm-system.h b/src/nm-system.h
index 094f40ef..ae4e7d91 100644
--- a/src/nm-system.h
+++ b/src/nm-system.h
@@ -35,33 +35,31 @@
  * implemented in the backend files in backends/ directory
  */
 
-void			nm_system_device_flush_routes				(NMDevice *dev, int family);
-void			nm_system_device_flush_routes_with_iface	(const char *iface, int family);
+gboolean        nm_system_iface_flush_routes         (int ifindex, int family);
 
-gboolean		nm_system_replace_default_ip4_route   (const char *iface,
+gboolean		nm_system_replace_default_ip4_route   (int ifindex,
                                                        guint32 gw,
                                                        guint32 mss);
 
-gboolean		nm_system_replace_default_ip6_route   (const char *iface,
+gboolean		nm_system_replace_default_ip6_route   (int ifindex,
                                                        const struct in6_addr *gw);
 
-gboolean		nm_system_replace_default_ip4_route_vpn (const char *iface,
+gboolean		nm_system_replace_default_ip4_route_vpn (int ifindex,
                                                          guint32 ext_gw,
                                                          guint32 int_gw,
                                                          guint32 mss,
-                                                         const char *parent_iface,
+                                                         int parent_ifindex,
                                                          guint32 parent_mss);
 
 struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config);
 
 
-void			nm_system_device_flush_addresses			(NMDevice *dev, int family);
-void			nm_system_device_flush_addresses_with_iface	(const char *iface);
+gboolean        nm_system_iface_flush_addresses         (int ifindex, int family);
 
 void			nm_system_enable_loopback				(void);
 void			nm_system_update_dns					(void);
 
-gboolean		nm_system_apply_ip4_config              (const char *iface,
+gboolean		nm_system_apply_ip4_config              (int ifindex,
                                                          NMIP4Config *config,
                                                          int priority,
                                                          NMIP4ConfigCompareFlags flags);
@@ -76,22 +74,19 @@ int             nm_system_set_ip6_route                 (int ifindex,
                                                          int table,
                                                          struct rtnl_route **out_route);
 
-gboolean		nm_system_apply_ip6_config              (const char *iface,
+gboolean		nm_system_apply_ip6_config              (int ifindex,
                                                          NMIP6Config *config,
                                                          int priority,
                                                          NMIP6ConfigCompareFlags flags);
 
-gboolean		nm_system_device_set_up_down				(NMDevice *dev,
-                                                             gboolean up,
-                                                             gboolean *no_firmware);
-gboolean		nm_system_device_set_up_down_with_iface		(const char *iface,
-                                                             gboolean up,
-                                                             gboolean *no_firmware);
+gboolean        nm_system_iface_set_up                  (int ifindex,
+                                                         gboolean up,
+                                                         gboolean *no_firmware);
 
-gboolean        nm_system_device_is_up (NMDevice *device);
-gboolean        nm_system_device_is_up_with_iface (const char *iface);
+gboolean        nm_system_iface_is_up                   (int ifindex);
 
-gboolean		nm_system_device_set_mtu (const char *iface, guint32 mtu);
-gboolean		nm_system_device_set_mac (const char *iface, const struct ether_addr *mac);
+gboolean		nm_system_iface_set_mtu                 (int ifindex, guint32 mtu);
+
+gboolean		nm_system_iface_set_mac                 (int ifindex, const struct ether_addr *mac);
 
 #endif
diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c
index f9c66473..93d012fb 100644
--- a/src/nm-wifi-ap.c
+++ b/src/nm-wifi-ap.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
@@ -59,10 +59,6 @@ typedef struct
 	gboolean			fake;	/* Whether or not the AP is from a scan */
 	gboolean			broadcast;	/* Whether or not the AP is broadcasting (hidden) */
 	glong				last_seen;	/* Last time the AP was seen in a scan in seconds */
-
-	/* Things from user prefs/NetworkManagerInfo */
-	GTimeVal			timestamp;
-	GSList *			user_addresses;
 } NMAccessPointPrivate;
 
 #define NM_AP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP, NMAccessPointPrivate))
@@ -112,8 +108,6 @@ finalize (GObject *object)
 	g_free (priv->dbus_path);
 	if (priv->ssid)
 		g_byte_array_free (priv->ssid, TRUE);
-	g_slist_foreach (priv->user_addresses, (GFunc)g_free, NULL);
-	g_slist_free (priv->user_addresses);
 
 	G_OBJECT_CLASS (nm_ap_parent_class)->finalize (object);
 }
@@ -773,7 +767,6 @@ nm_ap_print_self (NMAccessPoint *ap,
 	            ap);
 	nm_log_dbg (LOGD_WIFI_SCAN, "    BSSID     " MAC_FMT, MAC_ARG (priv->address.ether_addr_octet));
 	nm_log_dbg (LOGD_WIFI_SCAN, "    mode      %d", priv->mode);
-	nm_log_dbg (LOGD_WIFI_SCAN, "    timestamp %ld", priv->timestamp.tv_sec);
 	nm_log_dbg (LOGD_WIFI_SCAN, "    flags     0x%X", priv->flags);
 	nm_log_dbg (LOGD_WIFI_SCAN, "    wpa flags 0x%X", priv->wpa_flags);
 	nm_log_dbg (LOGD_WIFI_SCAN, "    rsn flags 0x%X", priv->rsn_flags);
@@ -791,37 +784,6 @@ nm_ap_get_dbus_path (NMAccessPoint *ap)
 	return NM_AP_GET_PRIVATE (ap)->dbus_path;
 }
 
-
-/*
- * Get/set functions for timestamp
- *
- */
-const GTimeVal *nm_ap_get_timestamp (const NMAccessPoint *ap)
-{
-	g_return_val_if_fail (NM_IS_AP (ap), 0);
-
-	return (&NM_AP_GET_PRIVATE (ap)->timestamp);
-}
-
-void nm_ap_set_timestamp (NMAccessPoint *ap, glong sec, glong usec)
-{
-	NMAccessPointPrivate *priv;
-
-	g_return_if_fail (NM_IS_AP (ap));
-
-	priv = NM_AP_GET_PRIVATE (ap);
-
-	priv->timestamp.tv_sec = sec;
-	priv->timestamp.tv_usec = usec;
-}
-
-void nm_ap_set_timestamp_via_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp)
-{
-	g_return_if_fail (NM_IS_AP (ap));
-
-	NM_AP_GET_PRIVATE (ap)->timestamp = *timestamp;
-}
-
 /*
  * Get/set functions for ssid
  *
@@ -1151,57 +1113,6 @@ void nm_ap_set_last_seen (NMAccessPoint *ap, const glong last_seen)
 	NM_AP_GET_PRIVATE (ap)->last_seen = last_seen;
 }
 
-
-/*
- * Get/Set functions for user address list
- *
- * The internal address list is always "owned" by the AP and
- * the list returned by nm_ap_get_user_addresses() is a deep copy.
- * Likewise, when setting the list, a deep copy is made for the
- * ap's actual list.
- *
- */
-GSList *nm_ap_get_user_addresses (const NMAccessPoint *ap)
-{
-	GSList	*new = NULL;
-	GSList	*elt = NULL;
-
-	g_return_val_if_fail (NM_IS_AP (ap), NULL);
-
-	for (elt = NM_AP_GET_PRIVATE (ap)->user_addresses; elt; elt = g_slist_next (elt))
-	{
-		if (elt->data)
-			new = g_slist_append (new, g_strdup (elt->data));
-	}
-
-	/* Return a _deep__copy_ of the address list */
-	return new;
-}
-
-void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list)
-{
-	NMAccessPointPrivate *priv;
-	GSList	*elt = NULL;
-	GSList	*new = NULL;
-
-	g_return_if_fail (NM_IS_AP (ap));
-
-	priv = NM_AP_GET_PRIVATE (ap);
-
-	/* Free existing list */
-	g_slist_foreach (priv->user_addresses, (GFunc) g_free, NULL);
-
-	/* Copy new list and set as our own */
-	for (elt = list; elt; elt = g_slist_next (elt))
-	{
-		if (elt->data)
-			new = g_slist_append (new, g_ascii_strup (elt->data, -1));
-	}
-
-	priv->user_addresses = new;
-}
-
-
 gboolean
 nm_ap_check_compatible (NMAccessPoint *self,
                         NMConnection *connection)
diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h
index 95514ba6..61e5b3b2 100644
--- a/src/nm-wifi-ap.h
+++ b/src/nm-wifi-ap.h
@@ -24,7 +24,6 @@
 
 #include <glib.h>
 #include <glib-object.h>
-#include <time.h>
 #include "NetworkManager.h"
 #include "nm-connection.h"
 
@@ -64,9 +63,6 @@ NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection);
 void            nm_ap_export_to_dbus    (NMAccessPoint *ap);
 
 const char *		nm_ap_get_dbus_path (NMAccessPoint *ap);
-const GTimeVal *	nm_ap_get_timestamp				(const NMAccessPoint *ap);
-void				nm_ap_set_timestamp				(NMAccessPoint *ap, glong sec, glong usec);
-void				nm_ap_set_timestamp_via_timestamp	(NMAccessPoint *ap, const GTimeVal *timestamp);
 
 const GByteArray *	nm_ap_get_ssid (const NMAccessPoint * ap);
 void				nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid);
@@ -104,9 +100,6 @@ void				nm_ap_set_broadcast		(NMAccessPoint *ap, gboolean broadcast);
 glong			nm_ap_get_last_seen		(const NMAccessPoint *ap);
 void				nm_ap_set_last_seen		(NMAccessPoint *ap, const glong last_seen);
 
-GSList *			nm_ap_get_user_addresses	(const NMAccessPoint *ap);
-void				nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
-
 gboolean			nm_ap_check_compatible (NMAccessPoint *self,
                                             NMConnection *connection);
 
diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in
index 13c60b41..0f0f6ab5 100644
--- a/src/ppp-manager/Makefile.in
+++ b/src/ppp-manager/Makefile.in
@@ -222,6 +222,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index e863aaba..522c0751 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -875,6 +875,8 @@ create_pppd_cmd_line (NMPPPManager *self,
 		nm_cmd_line_add_string (cmd, "refuse-mschap-v2");
 	if (nm_setting_ppp_get_nobsdcomp (setting))
 		nm_cmd_line_add_string (cmd, "nobsdcomp");
+	if (nm_setting_ppp_get_no_vj_comp (setting))
+		nm_cmd_line_add_string (cmd, "novj");
 	if (nm_setting_ppp_get_nodeflate (setting))
 		nm_cmd_line_add_string (cmd, "nodeflate");
 	if (nm_setting_ppp_get_require_mppe (setting))
diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in
index 980f35cb..b12742f0 100644
--- a/src/settings/Makefile.in
+++ b/src/settings/Makefile.in
@@ -248,6 +248,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 4b3a56cd..6a208529 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -84,15 +84,27 @@ typedef struct {
 
 	NMDBusManager *dbus_mgr;
 	NMAgentManager *agent_mgr;
+	NMSessionMonitor *session_monitor;
+	guint session_changed_id;
 
 	GSList *pending_auths; /* List of pending authentication requests */
-	NMConnection *secrets;
 	gboolean visible; /* Is this connection is visible by some session? */
-
 	GSList *reqs;  /* in-progress secrets requests */
 
-	NMSessionMonitor *session_monitor;
-	guint session_changed_id;
+	/* Caches secrets from on-disk connections; were they not cached any
+	 * call to nm_connection_clear_secrets() wipes them out and we'd have
+	 * to re-read them from disk which defeats the purpose of having the
+	 * connection in-memory at all.
+	 */
+	NMConnection *system_secrets;
+
+	/* Caches secrets from agents during the activation process; if new system
+	 * secrets are returned from an agent, they get written out to disk,
+	 * triggering a re-read of the connection, which reads only system
+	 * secrets, and would wipe out any agent-owned or not-saved secrets the
+	 * agent also returned.
+	 */
+	NMConnection *agent_secrets;
 
 	guint64 timestamp;   /* Up-to-date timestamp of connection use */
 	GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */
@@ -294,57 +306,67 @@ nm_settings_connection_check_permission (NMSettingsConnection *self,
 
 /**************************************************************/
 
-static void
-only_system_secrets_cb (NMSetting *setting,
-                        const char *key,
-                        const GValue *value,
-                        GParamFlags flags,
-                        gpointer user_data)
+static gboolean
+secrets_filter_cb (NMSetting *setting,
+                   const char *secret,
+                   NMSettingSecretFlags flags,
+                   gpointer user_data)
 {
-	if (flags & NM_SETTING_PARAM_SECRET) {
-		NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+	NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data);
 
-		/* VPNs are special; need to handle each secret separately */
-		if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
-			GHashTableIter iter;
-			const char *secret_name = NULL;
+	/* Returns TRUE to remove the secret */
 
-			g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
-			while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
-				secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-				nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
-				if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
-					nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
-			}
-		} else {
-			nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
-			if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
-				g_object_set (G_OBJECT (setting), key, NULL, NULL);
-		}
-	}
+	/* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */
+	if (   (flags == NM_SETTING_SECRET_FLAG_NONE)
+	    && (filter_flags == NM_SETTING_SECRET_FLAG_NONE))
+		return FALSE;
+
+	/* Otherwise if the secret has at least one of the desired flags keep it */
+	return (flags & filter_flags) ? FALSE : TRUE;
 }
 
 static void
-update_secrets_cache (NMSettingsConnection *self)
+update_system_secrets_cache (NMSettingsConnection *self)
 {
 	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 
-	if (priv->secrets)
-		g_object_unref (priv->secrets);
-	priv->secrets = nm_connection_duplicate (NM_CONNECTION (self));
+	if (priv->system_secrets)
+		g_object_unref (priv->system_secrets);
+	priv->system_secrets = nm_connection_duplicate (NM_CONNECTION (self));
 
 	/* Clear out non-system-owned and not-saved secrets */
-	nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL);
+	nm_connection_clear_secrets_with_flags (priv->system_secrets,
+	                                        secrets_filter_cb,
+	                                        GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_NONE));
 }
 
-static gboolean
-clear_system_secrets (GHashTableIter *iter,
-                      NMSettingSecretFlags flags,
-                      gpointer user_data)
+static void
+update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new)
 {
-	if (flags == NM_SETTING_SECRET_FLAG_NONE)
-		g_hash_table_iter_remove (iter);
-	return TRUE;
+	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+	NMSettingSecretFlags filter_flags = NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_AGENT_OWNED;
+
+	if (priv->agent_secrets)
+		g_object_unref (priv->agent_secrets);
+	priv->agent_secrets = nm_connection_duplicate (new ? new : NM_CONNECTION (self));
+
+	/* Clear out non-system-owned secrets */
+	nm_connection_clear_secrets_with_flags (priv->agent_secrets,
+	                                        secrets_filter_cb,
+	                                        GUINT_TO_POINTER (filter_flags));
+}
+
+static void
+secrets_cleared_cb (NMSettingsConnection *self)
+{
+	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+	/* Clear agent secrets when connection's secrets are cleared since agent
+	 * secrets are transient.
+	 */
+	if (priv->agent_secrets)
+		g_object_unref (priv->agent_secrets);
+	priv->agent_secrets = NULL;
 }
 
 /* Update the settings of this connection to match that of 'new', taking care to
@@ -356,7 +378,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
                                          GError **error)
 {
 	NMSettingsConnectionPrivate *priv;
-	GHashTable *new_settings, *transient_secrets;
+	GHashTable *new_settings, *hash = NULL;
 	gboolean success = FALSE;
 
 	g_return_val_if_fail (self != NULL, FALSE);
@@ -366,37 +388,29 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
 
 	priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 
-	/* Replacing the settings might replace transient secrets, such as when
-	 * a user agent returns secrets, which might trigger the connection to be
-	 * written out, which triggers an inotify event to re-read and update the
-	 * connection, which, if we're not careful, could wipe out the transient
-	 * secrets the user agent just sent us.  Basically, only
-	 * nm_connection_clear_secrets() should wipe out transient secrets but
-	 * re-reading a connection from on-disk and updating our in-memory copy
-	 * should not.  Thus we preserve non-system-owned secrets here.
-	 */
-	transient_secrets = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS);
-	if (transient_secrets)
-		for_each_secret (NM_CONNECTION (self), transient_secrets, clear_system_secrets, NULL);
-
 	new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL);
 	g_assert (new_settings);
 	if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) {
-		/* Copy the connection to keep its secrets around even if NM
-		 * calls nm_connection_clear_secrets().
+		/* Cache the just-updated system secrets in case something calls
+		 * nm_connection_clear_secrets() and clears them.
 		 */
-		update_secrets_cache (self);
+		update_system_secrets_cache (self);
+		success = TRUE;
 
-		/* And add the transient secrets back */
-		if (transient_secrets)
-			nm_connection_update_secrets (NM_CONNECTION (self), NULL, transient_secrets, NULL);
+		/* Add agent and always-ask secrets back; they won't necessarily be
+		 * in the replacement connection data if it was eg reread from disk.
+		 */
+		if (priv->agent_secrets) {
+			hash = nm_connection_to_hash (priv->agent_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+			if (hash) {
+				success = nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, error);
+				g_hash_table_destroy (hash);
+			}
+		}
 
 		nm_settings_connection_recheck_visibility (self);
-		success = TRUE;
 	}
 	g_hash_table_destroy (new_settings);
-	if (transient_secrets)
-		g_hash_table_destroy (transient_secrets);
 	return success;
 }
 
@@ -719,7 +733,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
 
 	/* Update the connection with our existing secrets from backing storage */
 	nm_connection_clear_secrets (NM_CONNECTION (self));
-	hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+	hash = nm_connection_to_hash (priv->system_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
 	if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) {
 		/* Update the connection with the agent's secrets; by this point if any
 		 * system-owned secrets exist in 'secrets' the agent that provided them
@@ -730,7 +744,8 @@ agent_secrets_done_cb (NMAgentManager *manager,
 			/* Now that all secrets are updated, copy and cache new secrets, 
 			 * then save them to backing storage.
 			 */
-			update_secrets_cache (self);
+			update_system_secrets_cache (self);
+			update_agent_secrets_cache (self, NULL);
 
 			/* Only save secrets to backing storage if the agent returned any
 			 * new system secrets.  If it didn't, then the secrets are agent-
@@ -807,11 +822,9 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
 	guint32 call_id = 0;
 
 	/* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
-	 * will clear secrets on this object's settings.  priv->secrets should be
-	 * a complete copy of this object and kept in sync by
-	 * nm_settings_connection_replace_settings().
+	 * will clear secrets on this object's settings.
 	 */
-	if (!priv->secrets) {
+	if (!priv->system_secrets) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 		             "%s.%d - Internal error; secrets cache invalid.",
 		             __FILE__, __LINE__);
@@ -826,7 +839,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
 		return 0;
 	}
 
-	existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+	existing_secrets = nm_connection_to_hash (priv->system_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
 	call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
 	                                        NM_CONNECTION (self),
 	                                        filter_by_uid,
@@ -1084,47 +1097,40 @@ impl_settings_connection_get_settings (NMSettingsConnection *self,
 	auth_start (self, context, NULL, get_settings_auth_cb, NULL);
 }
 
+typedef struct {
+	DBusGMethodInvocation *context;
+	NMAgentManager *agent_mgr;
+	gulong sender_uid;
+} UpdateInfo;
+
 static void
-con_update_cb (NMSettingsConnection *connection,
+con_update_cb (NMSettingsConnection *self,
                GError *error,
                gpointer user_data)
 {
-	DBusGMethodInvocation *context = user_data;
+	UpdateInfo *info = user_data;
+	NMConnection *for_agent;
 
 	if (error)
-		dbus_g_method_return_error (context, error);
-	else
-		dbus_g_method_return (context);
-}
-
-static void
-secrets_filter_cb (NMSetting *setting,
-                   const char *key,
-                   const GValue *value,
-                   GParamFlags flags,
-                   gpointer user_data)
-{
-	NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data);
-	NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-	const char *secret_name = NULL;
-	GHashTableIter iter;
+		dbus_g_method_return_error (info->context, error);
+	else {
+		/* Dupe the connection so we can clear out non-agent-owned secrets,
+		 * as agent-owned secrets are the only ones we send back be saved.
+		 * Only send secrets to agents of the same UID that called update too.
+		 */
+		for_agent = nm_connection_duplicate (NM_CONNECTION (self));
+		nm_connection_clear_secrets_with_flags (for_agent,
+		                                        secrets_filter_cb,
+		                                        GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
+		nm_agent_manager_save_secrets (info->agent_mgr, for_agent, TRUE, info->sender_uid);
+		g_object_unref (for_agent);
 
-	if (flags & NM_SETTING_PARAM_SECRET) {
-		if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
-			/* VPNs are special; need to handle each secret separately */
-			g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
-			while (g_hash_table_iter_next (&iter, (gpointer) &secret_name, NULL)) {
-				secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-				nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
-				if (!(secret_flags & filter_flags))
-					nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
-			}
-		} else {
-			nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
-			if (!(secret_flags & filter_flags))
-				g_object_set (G_OBJECT (setting), key, NULL, NULL);
-		}
+		dbus_g_method_return (info->context);
 	}
+
+	g_object_unref (info->agent_mgr);
+	memset (info, 0, sizeof (*info));
+	g_free (info);
 }
 
 static void
@@ -1136,54 +1142,27 @@ update_auth_cb (NMSettingsConnection *self,
 {
 	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 	NMConnection *new_settings = data;
-	NMConnection *for_agent, *dup;
-	NMSettingSecretFlags filter_flags;
-	GHashTable *hash;
-	GError *local = NULL;
+	UpdateInfo *info;
 
 	if (error)
 		dbus_g_method_return_error (context, error);
 	else {
-		/* Cache the new secrets since they may get overwritten by the replace
-		 * when transient secrets are copied back.
+		info = g_malloc0 (sizeof (*info));
+		info->context = context;
+		info->agent_mgr = g_object_ref (priv->agent_mgr);
+		info->sender_uid = sender_uid;
+
+		/* Cache the new secrets from the agent, as stuff like inotify-triggered
+		 * changes to connection's backing config files will blow them away if
+		 * they're in the main connection.
 		 */
-		dup = nm_connection_duplicate (new_settings);
+		update_agent_secrets_cache (self, new_settings);
 
 		/* Update and commit our settings. */
 		nm_settings_connection_replace_and_commit (self,
-		                                           new_settings,
-		                                           con_update_cb,
-		                                           context);
-
-		/* Copy new agent secrets back to the connection */
-		filter_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED;
-		nm_connection_for_each_setting_value (dup,
-		                                      secrets_filter_cb,
-		                                      GUINT_TO_POINTER (filter_flags));
-		hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
-		g_object_unref (dup);
-
-		if (hash) {
-			if (!nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, &local)) {
-				nm_log_warn (LOGD_SETTINGS, "Failed to update connection secrets: (%d) %s",
-				             local ? local->code : -1,
-				             local && local->message ? local->message : "(unknown)");
-				g_clear_error (&local);
-			}
-			g_hash_table_destroy (hash);
-		}
-
-		/* Dupe the connection and clear out non-agent-owned secrets so we can
-		 * send the agent-owned ones to agents to be saved.  Only send them to
-		 * agents of the same UID as the Update() request sender.
-		 */
-		for_agent = nm_connection_duplicate (NM_CONNECTION (self));
-		filter_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED;
-		nm_connection_for_each_setting_value (for_agent,
-		                                      secrets_filter_cb,
-		                                      GUINT_TO_POINTER (filter_flags));
-		nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, sender_uid);
-		g_object_unref (for_agent);
+			                                       new_settings,
+			                                       con_update_cb,
+			                                       info);
 	}
 
 	g_object_unref (new_settings);
@@ -1345,16 +1324,11 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
 	if (error)
 		dbus_g_method_return_error (context, error);
 	else {
-		/* The connection's secrets will have been updated by the agent manager,
-		 * so we want to refresh the secrets cache.  Note that we will never save
-		 * new secrets to backing storage here because D-Bus initated requests will
-		 * never ask for completely new secrets from agents.  Thus system-owned
-		 * secrets should not have changed from backing storage.  We also don't
-		 * send agent-owned secrets back out to be saved since we assume the agent
-		 * that provided the secrets saved them itself.
+		/* Return secrets from agent and backing storage to the D-Bus caller;
+		 * nm_settings_connection_get_secrets() will have updated itself with
+		 * secrets from backing storage and those returned from the agent
+		 * by the time we get here.
 		 */
-		update_secrets_cache (self);
-
 		hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS);
 		if (!hash)
 			hash = g_hash_table_new (NULL, NULL);
@@ -1726,6 +1700,8 @@ nm_settings_connection_init (NMSettingsConnection *self)
 	priv->agent_mgr = nm_agent_manager_get ();
 
 	priv->seen_bssids = g_hash_table_new_full (mac_hash, mac_equal, g_free, g_free);
+
+	g_signal_connect (self, "secrets-cleared", G_CALLBACK (secrets_cleared_cb), NULL);
 }
 
 static void
@@ -1739,8 +1715,10 @@ dispose (GObject *object)
 		goto out;
 	priv->disposed = TRUE;
 
-	if (priv->secrets)
-		g_object_unref (priv->secrets);
+	if (priv->system_secrets)
+		g_object_unref (priv->system_secrets);
+	if (priv->agent_secrets)
+		g_object_unref (priv->agent_secrets);
 
 	/* Cancel PolicyKit requests */
 	for (iter = priv->pending_auths; iter; iter = g_slist_next (iter))
diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in
index 148e9620..f22610dd 100644
--- a/src/settings/plugins/Makefile.in
+++ b/src/settings/plugins/Makefile.in
@@ -197,6 +197,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in
index f02b6431..1a2e9b77 100644
--- a/src/settings/plugins/ifcfg-rh/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/Makefile.in
@@ -267,6 +267,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index ed0dceca..b4be4cba 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -655,8 +655,10 @@ sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
 	}
 
 	if (!success) {
-		dbus_g_connection_unref (priv->bus);
-		priv->bus = NULL;
+		if (priv->bus) {
+			dbus_g_connection_unref (priv->bus);
+			priv->bus = NULL;
+		}
 	}
 }
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
index cd37d0a7..fa0298a4 100644
--- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
@@ -228,6 +228,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
index a10cbb86..087768e4 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
@@ -152,6 +152,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in
index 02e2247a..8c1ab0fd 100644
--- a/src/settings/plugins/ifcfg-suse/Makefile.in
+++ b/src/settings/plugins/ifcfg-suse/Makefile.in
@@ -215,6 +215,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in
index 2bc7bc32..4f50be2e 100644
--- a/src/settings/plugins/ifnet/Makefile.in
+++ b/src/settings/plugins/ifnet/Makefile.in
@@ -263,6 +263,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c
index 982f94f9..b4aaa8d2 100644
--- a/src/settings/plugins/ifnet/connection_parser.c
+++ b/src/settings/plugins/ifnet/connection_parser.c
@@ -1742,27 +1742,27 @@ ifnet_update_connection_from_config_block (const char *conn_name, GError **error
 
 	/* IPv4 setting */
 	make_ip4_setting (connection, conn_name, error);
-	if (error && *error)
-		PLUGIN_WARN (IFNET_PLUGIN_NAME,
-			     "Found error: %s", (*error)->message);
+	if (error && *error) {
+		PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message);
+		goto error;
+	}
 
 	/* IPv6 setting */
 	make_ip6_setting (connection, conn_name, error);
-	if (error && *error)
-		PLUGIN_WARN (IFNET_PLUGIN_NAME,
-			     "Found error: %s", (*error)->message);
+	if (error && *error) {
+		PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message);
+		goto error;
+	}
 
 	success = nm_connection_verify (connection, error);
 	if (error && *error)
-		PLUGIN_WARN (IFNET_PLUGIN_NAME,
-			     "Found error: %s", (*error)->message);
+		PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message);
 	PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, success);
 	if (!success)
 		goto error;
 	return connection;
 
 error:
-	g_object_unref (setting);
 	g_object_unref (connection);
 	return NULL;
 }
diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in
index 17b80c36..8ed45a66 100644
--- a/src/settings/plugins/ifnet/tests/Makefile.in
+++ b/src/settings/plugins/ifnet/tests/Makefile.in
@@ -186,6 +186,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net
index e7550002..0eef399a 100644
--- a/src/settings/plugins/ifnet/tests/net
+++ b/src/settings/plugins/ifnet/tests/net
@@ -35,6 +35,8 @@ config_eth6=("192.168.4.{1..101}/24")
 config_eth7=( "dhcp" )
 auto_eth7="true"
 
+# missing config_eth8
+auto_eth8="true"
 
 config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255")
 routes_myxjtu2=("default via 202.117.16.1")
diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c
index d114bbba..52d9ce2a 100644
--- a/src/settings/plugins/ifnet/tests/test_all.c
+++ b/src/settings/plugins/ifnet/tests/test_all.c
@@ -252,25 +252,25 @@ test_is_unmanaged ()
 static void
 test_new_connection ()
 {
-	GError **error = NULL;
+	GError *error = NULL;
 	NMConnection *connection;
 
-	connection = ifnet_update_connection_from_config_block ("eth2", error);
+	connection = ifnet_update_connection_from_config_block ("eth2", &error);
 	ASSERT (connection != NULL, "new connection",
 		"new connection failed: %s",
-		error == NULL ? "None" : (*error)->message);
+		error ? error->message : "None");
 	g_object_unref (connection);
-	connection =
-	    ifnet_update_connection_from_config_block ("qiaomuf", error);
+
+	connection = ifnet_update_connection_from_config_block ("qiaomuf", &error);
 	ASSERT (connection != NULL, "new connection",
-		"new connection failed: %s", error
-		&& (*error) ? (*error)->message : "NONE");
+		"new connection failed: %s",
+		error ? error->message : "NONE");
 	g_object_unref (connection);
-	connection =
-	    ifnet_update_connection_from_config_block ("myxjtu2", error);
+
+	connection = ifnet_update_connection_from_config_block ("myxjtu2", &error);
 	ASSERT (connection != NULL, "new connection",
-		"new connection failed: %s", error
-		&& (*error) ? (*error)->message : "NONE");
+		"new connection failed: %s",
+		error ? error->message : "NONE");
 	g_object_unref (connection);
 }
 
@@ -280,32 +280,32 @@ test_new_connection ()
 static void
 test_update_connection ()
 {
-	GError **error = NULL;
+	GError *error = NULL;
 	NMConnection *connection;
 	gboolean success;
 
-	connection = ifnet_update_connection_from_config_block ("eth0", error);
+	connection = ifnet_update_connection_from_config_block ("eth0", &error);
 	ASSERT (connection != NULL, "get connection",
 		"get connection failed: %s",
-		error == NULL ? "None" : (*error)->message);
+		error ? error->message : "None");
 
 	success = ifnet_update_parsers_by_connection (connection, "eth0",
 	                                              NET_GEN_NAME,
 	                                              SUP_GEN_NAME,
 	                                              NULL,
-	                                              error);
+	                                              &error);
 	ASSERT (success, "update connection", "update connection failed %s", "eth0");
 	g_object_unref (connection);
 
-	connection = ifnet_update_connection_from_config_block ("0xab3ace", error);
+	connection = ifnet_update_connection_from_config_block ("0xab3ace", &error);
 	ASSERT (connection != NULL, "get connection", "get connection failed: %s",
-		error == NULL ? "None" : (*error)->message);
+		error ? error->message : "None");
 
 	success = ifnet_update_parsers_by_connection (connection, "0xab3ace",
 	                                              NET_GEN_NAME,
 	                                              SUP_GEN_NAME,
 	                                              NULL,
-	                                              error);
+	                                              &error);
 	ASSERT (success, "update connection", "update connection failed %s", "0xab3ace");
 	g_object_unref (connection);
 
@@ -357,6 +357,17 @@ test_delete_connection ()
 }
 
 static void
+test_missing_config ()
+{
+	GError *error = NULL;
+	NMConnection *connection;
+
+	connection = ifnet_update_connection_from_config_block ("eth8", &error);
+	ASSERT (connection == NULL && error != NULL, "get connection",
+	        "get connection should fail with 'Unknown config for eth8'");
+}
+
+static void
 run_all (gboolean run)
 {
 	if (run) {
@@ -378,6 +389,7 @@ run_all (gboolean run)
 		test_update_connection ();
 		test_add_connection ();
 		test_delete_connection ();
+		test_missing_config ();
 	}
 }
 
diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
index a2595d42..4f5f68cf 100644
--- a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
+++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
@@ -859,6 +859,7 @@ network={
 	identity="user@example.com"
 	anonymous_identity="anonymous@example.com"
 	password="foobar"
-	ca_cert="blob://exampleblob"
+	ca_cert="test_ca_cert.pem"
+	phase2="auth=CHAP"
 	priority=20
 }
diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in
index 5f5a456b..142dcc55 100644
--- a/src/settings/plugins/ifupdown/Makefile.in
+++ b/src/settings/plugins/ifupdown/Makefile.in
@@ -262,6 +262,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in
index 7412e65d..1f82564f 100644
--- a/src/settings/plugins/ifupdown/tests/Makefile.in
+++ b/src/settings/plugins/ifupdown/tests/Makefile.in
@@ -186,6 +186,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in
index a2a7d231..c55f22ec 100644
--- a/src/settings/plugins/keyfile/Makefile.in
+++ b/src/settings/plugins/keyfile/Makefile.in
@@ -238,6 +238,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in
index 05ed3a61..7c1ed454 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/Makefile.in
@@ -224,6 +224,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
index 083615b0..b2c872f5 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
@@ -152,6 +152,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index 060093ce..5cfe5a54 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -993,15 +993,27 @@ _internal_write_connection (NMConnection *connection,
 
 		path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection));
 		if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-			/* Hmm, this is odd. Give up. */
-			g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
-				         "%s.%d: could not find suitable keyfile file name (%s already used)",
-				         __FILE__, __LINE__, path);
-			g_free (path);
-			goto out;
+			if (existing_path == NULL || g_strcmp0 (path, existing_path) != 0) {
+				/* This should not happen. But, it actually occurs when
+				 * two connections have the same UUID, and one of the connections
+				 * is edited to contain the same ID as the other one.
+				 * Give up.
+				 */
+				g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+				                    "%s.%d: could not find suitable keyfile file name (%s already used)",
+				                    __FILE__, __LINE__, path);
+				g_free (path);
+				goto out;
+			}
 		}
 	}
 
+	/* In case of updating the connection and changing the file path,
+	 * we need to remove the old one, not to end up with two connections.
+	 */
+	if (existing_path != NULL && strcmp (path, existing_path) != 0)
+		unlink (existing_path);
+
 	g_file_set_contents (path, data, len, error);
 	if (chown (path, owner_uid, owner_grp) < 0) {
 		g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in
index 33c4bd38..c680d008 100644
--- a/src/settings/tests/Makefile.in
+++ b/src/settings/tests/Makefile.in
@@ -188,6 +188,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in
index 729917d3..724c34e7 100644
--- a/src/supplicant-manager/Makefile.in
+++ b/src/supplicant-manager/Makefile.in
@@ -229,6 +229,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index c651e0fa..4860314b 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -123,7 +123,7 @@ nm_supplicant_config_add_option_with_type (NMSupplicantConfig *self,
 			char buf[255];
 			memset (&buf[0], 0, sizeof (buf));
 			memcpy (&buf[0], value, len > 254 ? 254 : len);
-			nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or value '%s' invalid.", key, buf);
+			nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or value '%s' invalid.", key, secret ? "<omitted>" : buf);
 			return FALSE;
 		}
 	}
diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in
index 18288c6e..61f70d7b 100644
--- a/src/supplicant-manager/tests/Makefile.in
+++ b/src/supplicant-manager/tests/Makefile.in
@@ -188,6 +188,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 0f19b712..9d848125 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -205,6 +205,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in
index 3785667e..02335d88 100644
--- a/src/vpn-manager/Makefile.in
+++ b/src/vpn-manager/Makefile.in
@@ -190,6 +190,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 067b2dce..75ba6451 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -46,6 +46,7 @@
 #include "NetworkManagerUtils.h"
 #include "nm-dns-manager.h"
 #include "nm-netlink-monitor.h"
+#include "nm-netlink-utils.h"
 #include "nm-glib-compat.h"
 #include "settings/nm-settings-connection.h"
 
@@ -86,6 +87,7 @@ typedef struct {
 	NMIP4Config *ip4_config;
 	guint32 ip4_internal_gw;
 	char *ip_iface;
+	int ip_ifindex;
 	char *banner;
 
 	struct rtnl_route *gw_route;
@@ -424,6 +426,13 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 		goto error;
 	}
 
+	/* Grab the interface index for address/routing operations */
+	priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface);
+	if (!priv->ip_ifindex) {
+		nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface);
+		goto error;
+	}
+
 	addr = nm_ip4_address_new ();
 	nm_ip4_address_set_prefix (addr, 24); /* default to class C */
 
@@ -529,9 +538,9 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG));
 	nm_utils_merge_ip4_config (config, s_ip4);
 
-	nm_system_device_set_up_down_with_iface (priv->ip_iface, TRUE, NULL);
+	nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL);
 
-	if (nm_system_apply_ip4_config (priv->ip_iface, config, 0, NM_IP4_COMPARE_FLAG_ALL)) {
+	if (nm_system_apply_ip4_config (priv->ip_ifindex, config, 0, NM_IP4_COMPARE_FLAG_ALL)) {
 		NMDnsManager *dns_mgr;
 
 		/* Add any explicit route to the VPN gateway through the parent device */
@@ -765,6 +774,14 @@ nm_vpn_connection_get_ip_iface (NMVPNConnection *connection)
 	return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_iface;
 }
 
+int
+nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection)
+{
+	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), -1);
+
+	return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_ifindex;
+}
+
 NMDevice *
 nm_vpn_connection_get_parent_device (NMVPNConnection *connection)
 {
@@ -940,11 +957,11 @@ vpn_cleanup (NMVPNConnection *connection)
 {
 	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-	if (priv->ip_iface) {
-		nm_system_device_set_up_down_with_iface (priv->ip_iface, FALSE, NULL);
+	if (priv->ip_ifindex) {
+		nm_system_iface_set_up (priv->ip_ifindex, FALSE, NULL);
 		/* FIXME: use AF_UNSPEC here when we have IPv6 support */
-		nm_system_device_flush_routes_with_iface (priv->ip_iface, AF_INET);
-		nm_system_device_flush_addresses_with_iface (priv->ip_iface);
+		nm_system_iface_flush_routes (priv->ip_ifindex, AF_INET);
+		nm_system_iface_flush_addresses (priv->ip_ifindex, AF_UNSPEC);
 	}
 
 	if (priv->ip4_config) {
@@ -958,12 +975,12 @@ vpn_cleanup (NMVPNConnection *connection)
 
 		/* Remove any previously added VPN gateway host route */
 		if (priv->gw_route)
-			rtnl_route_del (nm_netlink_get_default_handle (), priv->gw_route, 0);
+			nm_netlink_route_delete (priv->gw_route);
 
 		/* Reset routes and addresses of the currently active device */
 		parent_config = nm_device_get_ip4_config (priv->parent_dev);
 		if (parent_config) {
-			if (!nm_system_apply_ip4_config (nm_device_get_ip_iface (priv->parent_dev),
+			if (!nm_system_apply_ip4_config (nm_device_get_ip_ifindex (priv->parent_dev),
 			                                 nm_device_get_ip4_config (priv->parent_dev),
 			                                 nm_device_get_priority (priv->parent_dev),
 			                                 NM_IP4_COMPARE_FLAG_ADDRESSES | NM_IP4_COMPARE_FLAG_ROUTES)) {
@@ -982,6 +999,7 @@ vpn_cleanup (NMVPNConnection *connection)
 
 	g_free (priv->ip_iface);
 	priv->ip_iface = NULL;
+	priv->ip_ifindex = 0;
 
 	/* Clear out connection secrets to ensure that the settings service
 	 * gets asked for them next time the connection is activated.
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index ee8eb5b6..daf9483c 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -72,6 +72,7 @@ void                 nm_vpn_connection_disconnect      (NMVPNConnection *connect
                                                         NMVPNConnectionStateReason reason);
 NMIP4Config *        nm_vpn_connection_get_ip4_config  (NMVPNConnection *connection);
 const char *         nm_vpn_connection_get_ip_iface    (NMVPNConnection *connection);
+int                  nm_vpn_connection_get_ip_ifindex  (NMVPNConnection *connection);
 NMDevice *           nm_vpn_connection_get_parent_device (NMVPNConnection *connection);
 guint32              nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection);
 
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c
index 6772bb18..da2cf25f 100644
--- a/src/vpn-manager/nm-vpn-manager.c
+++ b/src/vpn-manager/nm-vpn-manager.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
@@ -306,9 +306,9 @@ nm_vpn_manager_get_active_connections (NMVPNManager *self)
 	return list;
 }
 
-NMConnection *
-nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
-                                          const char *active_path)
+NMVPNConnection *
+nm_vpn_manager_get_vpn_connection_for_active (NMVPNManager *manager,
+                                              const char *active_path)
 {
 	NMVPNManagerPrivate *priv;
 	GHashTableIter iter;
@@ -327,13 +327,24 @@ nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
 
 			ac_path = nm_vpn_connection_get_active_connection_path (vpn);
 			if (ac_path && !strcmp (ac_path, active_path))
-				return nm_vpn_connection_get_connection (vpn);
+				return vpn;
 		}
 	}
 
 	return NULL;
 }
 
+NMConnection *
+nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
+                                          const char *active_path)
+{
+	NMVPNConnection *vpn_con;
+
+	vpn_con = nm_vpn_manager_get_vpn_connection_for_active (manager, active_path);
+
+	return vpn_con ? nm_vpn_connection_get_connection (vpn_con) : NULL;
+}
+
 static char *
 service_name_from_file (const char *path)
 {
diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h
index a899122c..41010323 100644
--- a/src/vpn-manager/nm-vpn-manager.h
+++ b/src/vpn-manager/nm-vpn-manager.h
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2005 - 2008 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
@@ -83,7 +83,10 @@ void nm_vpn_manager_add_active_connections (NMVPNManager *manager,
 
 GSList *nm_vpn_manager_get_active_connections (NMVPNManager *manager);
 
+NMVPNConnection *nm_vpn_manager_get_vpn_connection_for_active (NMVPNManager *manager,
+                                                               const char *active_path);
+
 NMConnection *nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
                                                         const char *active_path);
 
-#endif /* NM_VPN_VPN_MANAGER_H */
+#endif /* NM_VPN_MANAGER_H */
diff --git a/src/wimax/Makefile.in b/src/wimax/Makefile.in
index e6064bc6..655eca71 100644
--- a/src/wimax/Makefile.in
+++ b/src/wimax/Makefile.in
@@ -186,6 +186,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c
index 9dff503d..78651c3b 100644
--- a/src/wimax/nm-device-wimax.c
+++ b/src/wimax/nm-device-wimax.c
@@ -91,6 +91,9 @@ typedef struct {
 	struct ether_addr hw_addr;
 	guint activation_timeout_id;
 
+	/* Track whether stage1 (Prepare) is completed yet or not */
+	gboolean prepare_done;
+
 	guint sdk_action_defer_id;
 
 	guint link_timeout_id;
@@ -231,27 +234,25 @@ set_current_nsp (NMDeviceWimax *self, NMWimaxNsp *new_nsp)
 {
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 	NMWimaxNsp *old_nsp;
-	char *old_path = NULL;
+	gboolean path_changed = FALSE;
 
 	old_nsp = priv->current_nsp;
-	if (old_nsp) {
-		old_path = g_strdup (nm_wimax_nsp_get_dbus_path (old_nsp));
-		priv->current_nsp = NULL;
-	}
+	priv->current_nsp = NULL;
 
 	if (new_nsp)
 		priv->current_nsp = g_object_ref (new_nsp);
 
-	if (old_nsp)
-		g_object_unref (old_nsp);
+	if (old_nsp && new_nsp) {
+		path_changed = (g_strcmp0 (nm_wimax_nsp_get_dbus_path (old_nsp),
+		                           nm_wimax_nsp_get_dbus_path (new_nsp)) != 0);
+	}
 
 	/* Only notify if it's really changed */
-	if (   (!old_path && new_nsp)
-		|| (old_path && !new_nsp)
-	    || (old_path && new_nsp && strcmp (old_path, nm_wimax_nsp_get_dbus_path (new_nsp))))
+	if (old_nsp != new_nsp || path_changed)
 		g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
 
-	g_free (old_path);
+	if (old_nsp)
+		g_object_unref (old_nsp);
 }
 
 NMWimaxNsp *
@@ -390,7 +391,7 @@ real_take_down (NMDevice *device)
 static gboolean
 real_hw_is_up (NMDevice *device)
 {
-	return nm_system_device_is_up (device);
+	return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 }
 
 static gboolean
@@ -401,13 +402,13 @@ real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 	if (!priv->enabled || !priv->wimaxd_enabled)
 		return FALSE;
 
-	return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+	return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-	nm_system_device_set_up_down (dev, FALSE, NULL);
+	nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL);
 }
 
 static void
@@ -749,6 +750,8 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
 
 	set_current_nsp (NM_DEVICE_WIMAX (device), nsp);
 
+	priv->prepare_done = TRUE;
+
 	/* If the device is scanning, it won't connect, so we have to wait until
 	 * it's not scanning to proceed to stage 2.
 	 */
@@ -936,7 +939,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 		 * then check if we need to move to stage2 now that the device might be
 		 * ready.
 		 */
-		if (state == NM_DEVICE_STATE_PREPARE) {
+		if (state == NM_DEVICE_STATE_PREPARE && priv->prepare_done) {
 			if (   new_status == WIMAX_API_DEVICE_STATUS_Ready
 			    || new_status == WIMAX_API_DEVICE_STATUS_Connecting) {
 				nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self));
@@ -1130,18 +1133,22 @@ wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data)
 	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 
-	if (priv->sdk) {
-		/* Clear callbacks just in case we don't hold the last reference */
-		iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
+	if (!priv->sdk) {
+		nm_log_dbg (LOGD_WIMAX, "(%s): removed unhandled WiMAX interface", wmxsdk->ifname);
+		return;
+	}
 
-		wmxsdk_unref (priv->sdk);
-		priv->sdk = NULL;
+	nm_log_dbg (LOGD_WIMAX, "(%s): removed WiMAX interface", wmxsdk->ifname);
 
-		priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
-		nm_device_state_changed (NM_DEVICE (self),
-								 NM_DEVICE_STATE_UNAVAILABLE,
-								 NM_DEVICE_STATE_REASON_NONE);
-	}
+	/* Clear callbacks just in case we don't hold the last reference */
+	iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
+	wmxsdk_unref (priv->sdk);
+	priv->sdk = NULL;
+
+	priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
+	nm_device_state_changed (NM_DEVICE (self),
+							 NM_DEVICE_STATE_UNAVAILABLE,
+							 NM_DEVICE_STATE_REASON_NONE);
 }
 
 /*************************************************************************/
@@ -1277,6 +1284,9 @@ device_state_changed (NMDevice *device,
 	NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 
+	/* Reset our stage1 (Prepare) done marker since it's only valid while in stage1 */
+	priv->prepare_done = FALSE;
+
 	if (new_state < NM_DEVICE_STATE_DISCONNECTED)
 		remove_all_nsps (self);
 
@@ -1323,21 +1333,27 @@ wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data)
 	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 
-	/* If we now have the SDK, schedule an idle handler to start the device up */
-	if (!priv->sdk) {
-		priv->sdk = wmxsdk_ref (sdk);
-		iwmx_sdk_set_callbacks(priv->sdk,
-		                       wmx_state_change_cb,
-		                       wmx_media_status_cb,
-		                       wmx_connect_result_cb,
-		                       wmx_scan_result_cb,
-		                       wmx_removed_cb,
-		                       self);
-		iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);
-
-		if (!priv->sdk_action_defer_id)
-			priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
+	/* We only track one wmxsdk at a time because the WiMAX SDK is pretty stupid */
+	if (priv->sdk) {
+		nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX interface already known", sdk->ifname);
+		return;
 	}
+
+	nm_log_dbg (LOGD_WIMAX, "(%s): new WiMAX interface (%s)", sdk->ifname, sdk->name);
+
+	/* Now that we have an SDK, schedule an idle handler to start the device up */
+	priv->sdk = wmxsdk_ref (sdk);
+	iwmx_sdk_set_callbacks(priv->sdk,
+	                       wmx_state_change_cb,
+	                       wmx_media_status_cb,
+	                       wmx_connect_result_cb,
+	                       wmx_scan_result_cb,
+	                       wmx_removed_cb,
+	                       self);
+	iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);
+
+	if (!priv->sdk_action_defer_id)
+		priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
 }
 
 /*************************************************************************/
diff --git a/test/Makefile.in b/test/Makefile.in
index 852e33b2..e06f00b0 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -205,6 +205,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 2ff9f088..8604ba16 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -152,6 +152,12 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@