about summary refs log tree commit diff
path: root/callouts
diff options
context:
space:
mode:
Diffstat (limited to 'callouts')
-rw-r--r--callouts/Makefile.am60
-rw-r--r--callouts/Makefile.in180
-rw-r--r--callouts/nm-avahi-autoipd-action.c2
-rw-r--r--callouts/nm-dhcp-client-action.c336
-rw-r--r--callouts/nm-dhcp-client.conf13
-rw-r--r--callouts/nm-dispatcher-api.h (renamed from callouts/nm-dispatcher-action.h)17
-rw-r--r--callouts/nm-dispatcher-utils.c165
-rw-r--r--callouts/nm-dispatcher.c (renamed from callouts/nm-dispatcher-action.c)188
-rw-r--r--callouts/nm-dispatcher.xml6
-rw-r--r--callouts/org.freedesktop.nm_dispatcher.service.in2
-rw-r--r--callouts/tests/Makefile.am10
-rw-r--r--callouts/tests/Makefile.in50
-rw-r--r--callouts/tests/dispatcher-old-down1
-rw-r--r--callouts/tests/dispatcher-old-up1
-rw-r--r--callouts/tests/dispatcher-old-vpn-down1
-rw-r--r--callouts/tests/dispatcher-old-vpn-up1
-rw-r--r--callouts/tests/test-dispatcher-envp.c58
17 files changed, 351 insertions, 740 deletions
diff --git a/callouts/Makefile.am b/callouts/Makefile.am
index b27fdd79..a8c9026f 100644
--- a/callouts/Makefile.am
+++ b/callouts/Makefile.am
@@ -1,5 +1,17 @@
 SUBDIRS = . tests
 
+AM_CPPFLAGS = \
+	-I${top_srcdir}/include \
+	-I${top_builddir}/include \
+	-I${top_srcdir}/libnm-util \
+	-I${top_builddir}/libnm-util \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+	-DNMCONFDIR=\"$(nmconfdir)\" \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DLIBEXECDIR=\"$(libexecdir)\"
+
 ###########################################
 # Test libraries
 ###########################################
@@ -10,58 +22,29 @@ noinst_LTLIBRARIES = \
 
 dbusservicedir = $(DBUS_SYS_DIR)
 dbusservice_DATA = \
-	nm-dhcp-client.conf \
 	nm-dispatcher.conf \
 	nm-avahi-autoipd.conf
 
 libexec_PROGRAMS = \
-	nm-dhcp-client.action \
-	nm-dispatcher.action \
+	nm-dispatcher \
 	nm-avahi-autoipd.action
 
-nm_dhcp_client_action_SOURCES = \
-	nm-dhcp-client-action.c
-
-nm_dhcp_client_action_CPPFLAGS = \
-	$(DBUS_CFLAGS) \
-	-DNMCONFDIR=\"$(nmconfdir)\" \
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
-nm_dhcp_client_action_LDADD = $(DBUS_LIBS)
-
 
 nm_avahi_autoipd_action_SOURCES = \
 	nm-avahi-autoipd-action.c
 
-nm_avahi_autoipd_action_CPPFLAGS = 		\
-	$(DBUS_CFLAGS)						\
-	$(GLIB_CFLAGS)					\
-	-DSYSCONFDIR=\"$(sysconfdir)\"		\
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
 nm_avahi_autoipd_action_LDADD = \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
 
-nm_dispatcher_action_SOURCES = \
-	nm-dispatcher-action.c \
-	nm-dispatcher-action.h \
+nm_dispatcher_SOURCES = \
+	nm-dispatcher.c \
+	nm-dispatcher-api.h \
 	nm-dispatcher-utils.c \
 	nm-dispatcher-utils.h
 
-nm_dispatcher_action_CPPFLAGS = \
-	-I${top_srcdir} \
-	-I${top_srcdir}/include \
-	-I${top_builddir}/include \
-	-I${top_srcdir}/libnm-util \
-	-I${top_builddir}/libnm-util \
-	$(DBUS_CFLAGS) \
-	$(GLIB_CFLAGS) \
-	-DNMCONFDIR=\"$(nmconfdir)\" \
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
-nm_dispatcher_action_LDADD = \
+nm_dispatcher_LDADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
@@ -78,12 +61,7 @@ libtest_dispatcher_envp_la_SOURCES = \
 	nm-dispatcher-utils.h
 
 libtest_dispatcher_envp_la_CPPFLAGS = \
-	-I${top_srcdir}/include \
-	-I${top_builddir}/include \
-	-I${top_srcdir}/libnm-util \
-	-I${top_builddir}/libnm-util \
-	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS)
+	$(AM_CPPFLAGS)
 
 libtest_dispatcher_envp_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
@@ -110,6 +88,8 @@ edit = @sed \
 dispatcherdir=$(sysconfdir)/NetworkManager/dispatcher.d
 install-data-hook:
 	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)
+	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-down.d
+	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-up.d
 
 BUILT_SOURCES = nm-dispatcher-glue.h
 
diff --git a/callouts/Makefile.in b/callouts/Makefile.in
index 7a58e398..06abda44 100644
--- a/callouts/Makefile.in
+++ b/callouts/Makefile.in
@@ -80,13 +80,14 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-libexec_PROGRAMS = nm-dhcp-client.action$(EXEEXT) \
-	nm-dispatcher.action$(EXEEXT) nm-avahi-autoipd.action$(EXEEXT)
+libexec_PROGRAMS = nm-dispatcher$(EXEEXT) \
+	nm-avahi-autoipd.action$(EXEEXT)
 subdir = callouts
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
+	$(top_srcdir)/m4/compiler_warnings.m4 \
 	$(top_srcdir)/m4/gettext.m4 \
 	$(top_srcdir)/m4/gnome-code-coverage.m4 \
 	$(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \
@@ -122,22 +123,16 @@ am__installdirs = "$(DESTDIR)$(libexecdir)" \
 	"$(DESTDIR)$(udevrulesdir)"
 PROGRAMS = $(libexec_PROGRAMS)
 am_nm_avahi_autoipd_action_OBJECTS =  \
-	nm_avahi_autoipd_action-nm-avahi-autoipd-action.$(OBJEXT)
+	nm-avahi-autoipd-action.$(OBJEXT)
 nm_avahi_autoipd_action_OBJECTS =  \
 	$(am_nm_avahi_autoipd_action_OBJECTS)
 nm_avahi_autoipd_action_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
-am_nm_dhcp_client_action_OBJECTS =  \
-	nm_dhcp_client_action-nm-dhcp-client-action.$(OBJEXT)
-nm_dhcp_client_action_OBJECTS = $(am_nm_dhcp_client_action_OBJECTS)
-nm_dhcp_client_action_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_nm_dispatcher_action_OBJECTS =  \
-	nm_dispatcher_action-nm-dispatcher-action.$(OBJEXT) \
-	nm_dispatcher_action-nm-dispatcher-utils.$(OBJEXT)
-nm_dispatcher_action_OBJECTS = $(am_nm_dispatcher_action_OBJECTS)
-nm_dispatcher_action_DEPENDENCIES =  \
-	$(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
+am_nm_dispatcher_OBJECTS = nm-dispatcher.$(OBJEXT) \
+	nm-dispatcher-utils.$(OBJEXT)
+nm_dispatcher_OBJECTS = $(am_nm_dispatcher_OBJECTS)
+nm_dispatcher_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -173,13 +168,9 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libtest_dispatcher_envp_la_SOURCES) \
-	$(nm_avahi_autoipd_action_SOURCES) \
-	$(nm_dhcp_client_action_SOURCES) \
-	$(nm_dispatcher_action_SOURCES)
+	$(nm_avahi_autoipd_action_SOURCES) $(nm_dispatcher_SOURCES)
 DIST_SOURCES = $(libtest_dispatcher_envp_la_SOURCES) \
-	$(nm_avahi_autoipd_action_SOURCES) \
-	$(nm_dhcp_client_action_SOURCES) \
-	$(nm_dispatcher_action_SOURCES)
+	$(nm_avahi_autoipd_action_SOURCES) $(nm_dispatcher_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
 	install-data-recursive install-dvi-recursive \
@@ -300,12 +291,15 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
+DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DHCLIENT_PATH = @DHCLIENT_PATH@
 DHCPCD_PATH = @DHCPCD_PATH@
+DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
 DSYMUTIL = @DSYMUTIL@
@@ -330,7 +324,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
 GNUTLS_LIBS = @GNUTLS_LIBS@
 GREP = @GREP@
 GTKDOC_CHECK = @GTKDOC_CHECK@
-GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
 GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
@@ -375,12 +368,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNDP_CFLAGS = @LIBNDP_CFLAGS@
+LIBNDP_LIBS = @LIBNDP_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
 LIBSOUP_LIBS = @LIBSOUP_LIBS@
+LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@
+LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -397,6 +394,8 @@ MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
+NEWT_CFLAGS = @NEWT_CFLAGS@
+NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
@@ -424,11 +423,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
+PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
 SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
@@ -443,6 +447,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
 UUID_CFLAGS = @UUID_CFLAGS@
 UUID_LIBS = @UUID_LIBS@
+VALGRIND_RULES = @VALGRIND_RULES@
 VAPIGEN = @VAPIGEN@
 VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@
 VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@
@@ -505,6 +510,7 @@ psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+subdirs = @subdirs@
 sysconfdir = @sysconfdir@
 systemdsystemunitdir = @systemdsystemunitdir@
 target_alias = @target_alias@
@@ -515,7 +521,20 @@ with_dhclient = @with_dhclient@
 with_dhcpcd = @with_dhcpcd@
 with_netconfig = @with_netconfig@
 with_resolvconf = @with_resolvconf@
+with_valgrind = @with_valgrind@
 SUBDIRS = . tests
+AM_CPPFLAGS = \
+	-I${top_srcdir}/include \
+	-I${top_builddir}/include \
+	-I${top_srcdir}/libnm-util \
+	-I${top_builddir}/libnm-util \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+	-DNMCONFDIR=\"$(nmconfdir)\" \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DLIBEXECDIR=\"$(libexecdir)\"
+
 
 ###########################################
 # Test libraries
@@ -525,50 +544,23 @@ noinst_LTLIBRARIES = \
 
 dbusservicedir = $(DBUS_SYS_DIR)
 dbusservice_DATA = \
-	nm-dhcp-client.conf \
 	nm-dispatcher.conf \
 	nm-avahi-autoipd.conf
 
-nm_dhcp_client_action_SOURCES = \
-	nm-dhcp-client-action.c
-
-nm_dhcp_client_action_CPPFLAGS = \
-	$(DBUS_CFLAGS) \
-	-DNMCONFDIR=\"$(nmconfdir)\" \
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
-nm_dhcp_client_action_LDADD = $(DBUS_LIBS)
 nm_avahi_autoipd_action_SOURCES = \
 	nm-avahi-autoipd-action.c
 
-nm_avahi_autoipd_action_CPPFLAGS = \
-	$(DBUS_CFLAGS)						\
-	$(GLIB_CFLAGS)					\
-	-DSYSCONFDIR=\"$(sysconfdir)\"		\
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
 nm_avahi_autoipd_action_LDADD = \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
-nm_dispatcher_action_SOURCES = \
-	nm-dispatcher-action.c \
-	nm-dispatcher-action.h \
+nm_dispatcher_SOURCES = \
+	nm-dispatcher.c \
+	nm-dispatcher-api.h \
 	nm-dispatcher-utils.c \
 	nm-dispatcher-utils.h
 
-nm_dispatcher_action_CPPFLAGS = \
-	-I${top_srcdir} \
-	-I${top_srcdir}/include \
-	-I${top_builddir}/include \
-	-I${top_srcdir}/libnm-util \
-	-I${top_builddir}/libnm-util \
-	$(DBUS_CFLAGS) \
-	$(GLIB_CFLAGS) \
-	-DNMCONFDIR=\"$(nmconfdir)\" \
-	-DLIBEXECDIR=\"$(libexecdir)\"
-
-nm_dispatcher_action_LDADD = \
+nm_dispatcher_LDADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
@@ -582,12 +574,7 @@ libtest_dispatcher_envp_la_SOURCES = \
 	nm-dispatcher-utils.h
 
 libtest_dispatcher_envp_la_CPPFLAGS = \
-	-I${top_srcdir}/include \
-	-I${top_builddir}/include \
-	-I${top_srcdir}/libnm-util \
-	-I${top_builddir}/libnm-util \
-	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS)
+	$(AM_CPPFLAGS)
 
 libtest_dispatcher_envp_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
@@ -717,13 +704,9 @@ nm-avahi-autoipd.action$(EXEEXT): $(nm_avahi_autoipd_action_OBJECTS) $(nm_avahi_
 	@rm -f nm-avahi-autoipd.action$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(nm_avahi_autoipd_action_OBJECTS) $(nm_avahi_autoipd_action_LDADD) $(LIBS)
 
-nm-dhcp-client.action$(EXEEXT): $(nm_dhcp_client_action_OBJECTS) $(nm_dhcp_client_action_DEPENDENCIES) $(EXTRA_nm_dhcp_client_action_DEPENDENCIES) 
-	@rm -f nm-dhcp-client.action$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(nm_dhcp_client_action_OBJECTS) $(nm_dhcp_client_action_LDADD) $(LIBS)
-
-nm-dispatcher.action$(EXEEXT): $(nm_dispatcher_action_OBJECTS) $(nm_dispatcher_action_DEPENDENCIES) $(EXTRA_nm_dispatcher_action_DEPENDENCIES) 
-	@rm -f nm-dispatcher.action$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(nm_dispatcher_action_OBJECTS) $(nm_dispatcher_action_LDADD) $(LIBS)
+nm-dispatcher$(EXEEXT): $(nm_dispatcher_OBJECTS) $(nm_dispatcher_DEPENDENCIES) $(EXTRA_nm_dispatcher_DEPENDENCIES) 
+	@rm -f nm-dispatcher$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(nm_dispatcher_OBJECTS) $(nm_dispatcher_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -732,10 +715,9 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dispatcher_envp_la-nm-dispatcher-utils.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-avahi-autoipd-action.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dispatcher-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dispatcher.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -765,62 +747,6 @@ libtest_dispatcher_envp_la-nm-dispatcher-utils.lo: nm-dispatcher-utils.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_dispatcher_envp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtest_dispatcher_envp_la-nm-dispatcher-utils.lo `test -f 'nm-dispatcher-utils.c' || echo '$(srcdir)/'`nm-dispatcher-utils.c
 
-nm_avahi_autoipd_action-nm-avahi-autoipd-action.o: nm-avahi-autoipd-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_avahi_autoipd_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_avahi_autoipd_action-nm-avahi-autoipd-action.o -MD -MP -MF $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Tpo -c -o nm_avahi_autoipd_action-nm-avahi-autoipd-action.o `test -f 'nm-avahi-autoipd-action.c' || echo '$(srcdir)/'`nm-avahi-autoipd-action.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Tpo $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-avahi-autoipd-action.c' object='nm_avahi_autoipd_action-nm-avahi-autoipd-action.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_avahi_autoipd_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_avahi_autoipd_action-nm-avahi-autoipd-action.o `test -f 'nm-avahi-autoipd-action.c' || echo '$(srcdir)/'`nm-avahi-autoipd-action.c
-
-nm_avahi_autoipd_action-nm-avahi-autoipd-action.obj: nm-avahi-autoipd-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_avahi_autoipd_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_avahi_autoipd_action-nm-avahi-autoipd-action.obj -MD -MP -MF $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Tpo -c -o nm_avahi_autoipd_action-nm-avahi-autoipd-action.obj `if test -f 'nm-avahi-autoipd-action.c'; then $(CYGPATH_W) 'nm-avahi-autoipd-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-avahi-autoipd-action.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Tpo $(DEPDIR)/nm_avahi_autoipd_action-nm-avahi-autoipd-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-avahi-autoipd-action.c' object='nm_avahi_autoipd_action-nm-avahi-autoipd-action.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_avahi_autoipd_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_avahi_autoipd_action-nm-avahi-autoipd-action.obj `if test -f 'nm-avahi-autoipd-action.c'; then $(CYGPATH_W) 'nm-avahi-autoipd-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-avahi-autoipd-action.c'; fi`
-
-nm_dhcp_client_action-nm-dhcp-client-action.o: nm-dhcp-client-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_client_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dhcp_client_action-nm-dhcp-client-action.o -MD -MP -MF $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Tpo -c -o nm_dhcp_client_action-nm-dhcp-client-action.o `test -f 'nm-dhcp-client-action.c' || echo '$(srcdir)/'`nm-dhcp-client-action.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Tpo $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dhcp-client-action.c' object='nm_dhcp_client_action-nm-dhcp-client-action.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_client_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dhcp_client_action-nm-dhcp-client-action.o `test -f 'nm-dhcp-client-action.c' || echo '$(srcdir)/'`nm-dhcp-client-action.c
-
-nm_dhcp_client_action-nm-dhcp-client-action.obj: nm-dhcp-client-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_client_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dhcp_client_action-nm-dhcp-client-action.obj -MD -MP -MF $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Tpo -c -o nm_dhcp_client_action-nm-dhcp-client-action.obj `if test -f 'nm-dhcp-client-action.c'; then $(CYGPATH_W) 'nm-dhcp-client-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp-client-action.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Tpo $(DEPDIR)/nm_dhcp_client_action-nm-dhcp-client-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dhcp-client-action.c' object='nm_dhcp_client_action-nm-dhcp-client-action.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_client_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dhcp_client_action-nm-dhcp-client-action.obj `if test -f 'nm-dhcp-client-action.c'; then $(CYGPATH_W) 'nm-dhcp-client-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp-client-action.c'; fi`
-
-nm_dispatcher_action-nm-dispatcher-action.o: nm-dispatcher-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dispatcher_action-nm-dispatcher-action.o -MD -MP -MF $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Tpo -c -o nm_dispatcher_action-nm-dispatcher-action.o `test -f 'nm-dispatcher-action.c' || echo '$(srcdir)/'`nm-dispatcher-action.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Tpo $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dispatcher-action.c' object='nm_dispatcher_action-nm-dispatcher-action.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dispatcher_action-nm-dispatcher-action.o `test -f 'nm-dispatcher-action.c' || echo '$(srcdir)/'`nm-dispatcher-action.c
-
-nm_dispatcher_action-nm-dispatcher-action.obj: nm-dispatcher-action.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dispatcher_action-nm-dispatcher-action.obj -MD -MP -MF $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Tpo -c -o nm_dispatcher_action-nm-dispatcher-action.obj `if test -f 'nm-dispatcher-action.c'; then $(CYGPATH_W) 'nm-dispatcher-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-dispatcher-action.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Tpo $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-action.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dispatcher-action.c' object='nm_dispatcher_action-nm-dispatcher-action.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dispatcher_action-nm-dispatcher-action.obj `if test -f 'nm-dispatcher-action.c'; then $(CYGPATH_W) 'nm-dispatcher-action.c'; else $(CYGPATH_W) '$(srcdir)/nm-dispatcher-action.c'; fi`
-
-nm_dispatcher_action-nm-dispatcher-utils.o: nm-dispatcher-utils.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dispatcher_action-nm-dispatcher-utils.o -MD -MP -MF $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Tpo -c -o nm_dispatcher_action-nm-dispatcher-utils.o `test -f 'nm-dispatcher-utils.c' || echo '$(srcdir)/'`nm-dispatcher-utils.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Tpo $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dispatcher-utils.c' object='nm_dispatcher_action-nm-dispatcher-utils.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dispatcher_action-nm-dispatcher-utils.o `test -f 'nm-dispatcher-utils.c' || echo '$(srcdir)/'`nm-dispatcher-utils.c
-
-nm_dispatcher_action-nm-dispatcher-utils.obj: nm-dispatcher-utils.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dispatcher_action-nm-dispatcher-utils.obj -MD -MP -MF $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Tpo -c -o nm_dispatcher_action-nm-dispatcher-utils.obj `if test -f 'nm-dispatcher-utils.c'; then $(CYGPATH_W) 'nm-dispatcher-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-dispatcher-utils.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Tpo $(DEPDIR)/nm_dispatcher_action-nm-dispatcher-utils.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nm-dispatcher-utils.c' object='nm_dispatcher_action-nm-dispatcher-utils.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dispatcher_action_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dispatcher_action-nm-dispatcher-utils.obj `if test -f 'nm-dispatcher-utils.c'; then $(CYGPATH_W) 'nm-dispatcher-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-dispatcher-utils.c'; fi`
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -1190,6 +1116,8 @@ nm-dispatcher-glue.h: nm-dispatcher.xml
 	$(edit) $< >$@
 install-data-hook:
 	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)
+	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-down.d
+	   $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-up.d
 
 # 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/callouts/nm-avahi-autoipd-action.c b/callouts/nm-avahi-autoipd-action.c
index 440efade..f84eed71 100644
--- a/callouts/nm-avahi-autoipd-action.c
+++ b/callouts/nm-avahi-autoipd-action.c
@@ -90,7 +90,9 @@ main (int argc, char *argv[])
 	dbus_bool_t result;
 	char *event, *iface, *address;
 
+#if !GLIB_CHECK_VERSION (2, 35, 0)
 	g_type_init ();
+#endif
 
 	if (argc != 4) {
 		fprintf (stderr, "Error: expected 3 arguments (event, interface, address).\n");
diff --git a/callouts/nm-dhcp-client-action.c b/callouts/nm-dhcp-client-action.c
deleted file mode 100644
index 2553a61a..00000000
--- a/callouts/nm-dhcp-client-action.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* -*- 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) 2007 - 2012 Red Hat, Inc.
- */
-
-/* for environ */
-#define _GNU_SOURCE
-#include <config.h>
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <dbus/dbus.h>
-
-#define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client"
-#define NM_DHCP_CLIENT_DBUS_IFACE   "org.freedesktop.nm_dhcp_client"
-
-/**
- * Start a dict in a dbus message.  Should be paired with a call to
- * {@link wpa_dbus_dict_close_write}.
- *
- * @param iter A valid dbus message iterator
- * @param iter_dict (out) A dict iterator to pass to further dict functions
- * @return TRUE on success, FALSE on failure
- *
- */
-static dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
-				     DBusMessageIter *iter_dict)
-{
-	dbus_bool_t result;
-
-	if (!iter || !iter_dict)
-		return FALSE;
-
-	result = dbus_message_iter_open_container(
-		iter,
-		DBUS_TYPE_ARRAY,
-		DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-		DBUS_TYPE_STRING_AS_STRING
-		DBUS_TYPE_VARIANT_AS_STRING
-		DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
-		iter_dict);
-	return result;
-}
-
-/**
- * End a dict element in a dbus message.  Should be paired with
- * a call to {@link wpa_dbus_dict_open_write}.
- *
- * @param iter valid dbus message iterator, same as passed to
- *    wpa_dbus_dict_open_write()
- * @param iter_dict a dbus dict iterator returned from
- *    {@link wpa_dbus_dict_open_write}
- * @return TRUE on success, FALSE on failure
- *
- */
-static dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
-				      DBusMessageIter *iter_dict)
-{
-	if (!iter || !iter_dict)
-		return FALSE;
-
-	return dbus_message_iter_close_container(iter, iter_dict);
-}
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_start(
-	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
-	const char *key, const int value_type)
-{
-	if (!dbus_message_iter_open_container(iter_dict,
-					      DBUS_TYPE_DICT_ENTRY, NULL,
-					      iter_dict_entry))
-		return FALSE;
-
-	if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
-					    &key))
-		return FALSE;
-
-	return TRUE;
-}
-
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_end(
-	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
-	DBusMessageIter *iter_dict_val)
-{
-	if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
-		return FALSE;
-	if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
-		return FALSE;
-
-	return TRUE;
-}
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
-	DBusMessageIter *iter_dict, const char *key,
-	const char *value, const dbus_uint32_t value_len)
-{
-	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
-	dbus_uint32_t i;
-
-	if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
-					    key, DBUS_TYPE_ARRAY))
-		return FALSE;
-
-	if (!dbus_message_iter_open_container(&iter_dict_entry,
-					      DBUS_TYPE_VARIANT,
-					      DBUS_TYPE_ARRAY_AS_STRING
-					      DBUS_TYPE_BYTE_AS_STRING,
-					      &iter_dict_val))
-		return FALSE;
-
-	if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
-					      DBUS_TYPE_BYTE_AS_STRING,
-					      &iter_array))
-		return FALSE;
-
-	for (i = 0; i < value_len; i++) {
-		if (!dbus_message_iter_append_basic(&iter_array,
-						    DBUS_TYPE_BYTE,
-						    &(value[i])))
-			return FALSE;
-	}
-
-	if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
-		return FALSE;
-
-	if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
-					  &iter_dict_val))
-		return FALSE;
-
-	return TRUE;
-}
-
-/**
- * Add a byte array entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
- * @param key The key of the dict item
- * @param value The byte array
- * @param value_len The length of the byte array, in bytes
- * @return TRUE on success, FALSE on failure
- *
- */
-static dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
-					    const char *key,
-					    const char *value,
-					    const dbus_uint32_t value_len)
-{
-	if (!key)
-		return FALSE;
-	if (!value && (value_len != 0))
-		return FALSE;
-	return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
-						   value_len);
-}
-
-
-static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", NULL};
-
-static dbus_bool_t
-build_message (DBusMessage * message)
-{
-	char **item;
-	dbus_bool_t success = FALSE;
-	DBusMessageIter iter, iter_dict;
-
-	dbus_message_iter_init_append (message, &iter);
-	if (!wpa_dbus_dict_open_write (&iter, &iter_dict))
-		goto out;
-
-	/* List environment and format for dbus dict */
-	for (item = environ; *item; item++) {
-		char *name, *val, **p;
-
-		/* Split on the = */
-		name = strdup (*item);
-		val = strchr (name, '=');
-		if (!val)
-			goto next;
-		*val++ = '\0';
-		if (!strlen (val))
-			val = NULL;
-
-		/* Ignore non-DCHP-related environment variables */
-		for (p = (char **) ignore; *p; p++) {
-			if (strncmp (name, *p, strlen (*p)) == 0)
-				goto next;
-		}
-
-		/* Value passed as a byte array rather than a string, because there are
-		 * no character encoding guarantees with DHCP, and D-Bus requires
-		 * strings to be UTF-8.
-		 */
-		if (!wpa_dbus_dict_append_byte_array (&iter_dict,
-		                                      name,
-		                                      val ? val : "\0",
-		                                      val ? strlen (val) : 1)) {
-			fprintf (stderr, "Error: failed to add item '%s' to signal\n", name);
-		}
-
-	next:
-		free (name);
-	}
-
-	if (!wpa_dbus_dict_close_write (&iter, &iter_dict))
-		goto out;
-
-	success = TRUE;
-
-out:
-	return success;
-}
-
-static DBusConnection *
-dbus_init (void)
-{
-	DBusConnection * connection;
-	DBusError error;
-	int ret;
-
-	dbus_connection_set_change_sigpipe (TRUE);
-
-	dbus_error_init (&error);
-	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (dbus_error_is_set (&error)) {
-		fprintf (stderr, "Error: could not get the system bus.  Make sure "
-		            "the message bus daemon is running!  Message: (%s) %s\n",
-		            error.name,
-		            error.message);
-		goto error;
-	}
-
-	dbus_connection_set_exit_on_disconnect (connection, FALSE);
-
-	dbus_error_init (&error);
-	ret = dbus_bus_request_name (connection, NM_DHCP_CLIENT_DBUS_SERVICE, 0, &error);
-	if (dbus_error_is_set (&error)) {
-		fprintf (stderr, "Error: Could not acquire the NM DHCP client service. "
-		            "Message: (%s) %s\n",
-		            error.name,
-		            error.message);
-		goto error;
-	}
-
-	if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-		fprintf (stderr, "Error: Could not acquire the NM DHCP client service "
-		         "as it is already taken.  Return: %d\n",
-		         ret);
-		goto error;
-	}
-
-	return connection;
-
-error:
-	if (dbus_error_is_set (&error))
-		dbus_error_free (&error);
-	if (connection)
-		dbus_connection_unref (connection);
-	return NULL;
-}
-
-static void
-fatal_error (void)
-{
-	const char *pid_str = getenv ("pid");
-	int pid = 0;
-
-	if (pid_str)
-		pid = strtol (pid_str, NULL, 10);
-	if (pid) {
-		fprintf (stderr, "Fatal error occured, killing dhclient instance with pid %d.\n", pid);
-		kill (pid, SIGTERM);
-	}
-
-	exit (1);
-}
-
-int
-main (int argc, char *argv[])
-{
-	DBusConnection * connection;
-	DBusMessage * message;
-	dbus_bool_t result;
-
-	/* Get a connection to the system bus */
-	connection = dbus_init ();
-	if (connection == NULL)
-		fatal_error ();
-
-	message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event");
-	if (message == NULL) {
-		fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
-		fatal_error ();
-	}
-
-	/* Dump environment variables into the message */
-	result = build_message (message);
-	if (result == FALSE) {
-		fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
-		fatal_error ();
-	}
-
-	/* queue the message */
-	result = dbus_connection_send (connection, message, NULL);
-	if (!result) {
-		fprintf (stderr, "Error: Could not send send DHCP Event signal.\n");
-		fatal_error ();
-	}
-	dbus_message_unref (message);
-
-	/* Send out the message */
-	dbus_connection_flush (connection);
-
-	return 0;
-}
-
diff --git a/callouts/nm-dhcp-client.conf b/callouts/nm-dhcp-client.conf
deleted file mode 100644
index 0aeae603..00000000
--- a/callouts/nm-dhcp-client.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
-        <policy user="root">
-                <allow own="org.freedesktop.nm_dhcp_client"/>
-        </policy>
-        <policy context="default">
-                <deny own="org.freedesktop.nm_dhcp_client"/>
-		<deny send_destination="org.freedesktop.nm_dhcp_client"/>
-        </policy>
-</busconfig>
-
diff --git a/callouts/nm-dispatcher-action.h b/callouts/nm-dispatcher-api.h
index 9fea487a..03e40f77 100644
--- a/callouts/nm-dispatcher-action.h
+++ b/callouts/nm-dispatcher-api.h
@@ -20,6 +20,10 @@
 
 #include <dbus/dbus-glib.h>
 
+#define NMD_SCRIPT_DIR_DEFAULT  NMCONFDIR "/dispatcher.d"
+#define NMD_SCRIPT_DIR_PRE_UP   NMD_SCRIPT_DIR_DEFAULT "/pre-up.d"
+#define NMD_SCRIPT_DIR_PRE_DOWN NMD_SCRIPT_DIR_DEFAULT "/pre-down.d"
+
 /* dbus-glib types for dispatcher call return value */
 #define DISPATCHER_TYPE_RESULT       (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID))
 #define DISPATCHER_TYPE_RESULT_ARRAY (dbus_g_type_get_collection ("GPtrArray", DISPATCHER_TYPE_RESULT))
@@ -36,6 +40,19 @@
 #define NMD_DEVICE_PROPS_STATE            "state"
 #define NMD_DEVICE_PROPS_PATH             "path"
 
+/* Actions */
+#define NMD_ACTION_HOSTNAME     "hostname"
+#define NMD_ACTION_PRE_UP       "pre-up"
+#define NMD_ACTION_UP           "up"
+#define NMD_ACTION_PRE_DOWN     "pre-down"
+#define NMD_ACTION_DOWN         "down"
+#define NMD_ACTION_VPN_PRE_UP   "vpn-pre-up"
+#define NMD_ACTION_VPN_UP       "vpn-up"
+#define NMD_ACTION_VPN_PRE_DOWN "vpn-pre-down"
+#define NMD_ACTION_VPN_DOWN     "vpn-down"
+#define NMD_ACTION_DHCP4_CHANGE "dhcp4-change"
+#define NMD_ACTION_DHCP6_CHANGE "dhcp6-change"
+
 typedef enum {
 	DISPATCH_RESULT_UNKNOWN = 0,
 	DISPATCH_RESULT_SUCCESS = 1,
diff --git a/callouts/nm-dispatcher-utils.c b/callouts/nm-dispatcher-utils.c
index e5240a7d..b1d11daf 100644
--- a/callouts/nm-dispatcher-utils.c
+++ b/callouts/nm-dispatcher-utils.c
@@ -30,7 +30,7 @@
 #include <nm-setting-ip6-config.h>
 #include <nm-setting-connection.h>
 
-#include "nm-dispatcher-action.h"
+#include "nm-dispatcher-api.h"
 #include "nm-utils.h"
 
 #include "nm-dispatcher-utils.h"
@@ -96,6 +96,8 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
 	guint32 num, i;
 	GString *tmp;
 	GValue *val;
+	char str_addr[INET_ADDRSTRLEN];
+	char str_gw[INET_ADDRSTRLEN];
 
 	if (ip4_config == NULL)
 		return items;
@@ -110,30 +112,19 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
 
 	for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) {
 		NMIP4Address *addr = (NMIP4Address *) iter->data;
-		char str_addr[INET_ADDRSTRLEN + 1];
-		char str_gw[INET_ADDRSTRLEN + 1];
-		struct in_addr tmp_addr;
 		guint32 ip_prefix = nm_ip4_address_get_prefix (addr);
 		char *addrtmp;
 
-		memset (str_addr, 0, sizeof (str_addr));
-		tmp_addr.s_addr = nm_ip4_address_get_address (addr);
-		if (!inet_ntop (AF_INET, &tmp_addr, str_addr, sizeof (str_addr)))
-			continue;
-
-		memset (str_gw, 0, sizeof (str_gw));
-		tmp_addr.s_addr = nm_ip4_address_get_gateway (addr);
-		inet_ntop (AF_INET, &tmp_addr, str_gw, sizeof (str_gw));
+		nm_utils_inet4_ntop (nm_ip4_address_get_address (addr), str_addr);
+		nm_utils_inet4_ntop (nm_ip4_address_get_gateway (addr), str_gw);
 
 		addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw);
 		items = g_slist_prepend (items, addrtmp);
 	}
 	if (num)
 		items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, num));
-	if (addresses) {
-		g_slist_foreach (addresses, (GFunc) nm_ip4_address_unref, NULL);
-		g_slist_free (addresses);
-	}
+	if (addresses)
+		g_slist_free_full (addresses, (GDestroyNotify) nm_ip4_address_unref);
 
 	/* DNS servers */
 	val = g_hash_table_lookup (ip4_config, "nameservers");
@@ -146,17 +137,13 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
 		tmp = g_string_new (NULL);
 		g_string_append_printf (tmp, "%sIP4_NAMESERVERS=", prefix);
 		for (i = 0; i < dns->len; i++) {
-			struct in_addr addr;
-			char buf[INET_ADDRSTRLEN + 1];
-
-			addr.s_addr = g_array_index (dns, guint32, i);
-			memset (buf, 0, sizeof (buf));
-			if (inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
-				if (!first)
-					g_string_append_c (tmp, ' ');
-				g_string_append (tmp, buf);
-				first = FALSE;
-			}
+			guint32 addr;
+
+			addr = g_array_index (dns, guint32, i);
+			if (!first)
+				g_string_append_c (tmp, ' ');
+			g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL));
+			first = FALSE;
 		}
 		items = g_slist_prepend (items, tmp->str);
 		g_string_free (tmp, FALSE);
@@ -176,17 +163,13 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
 		tmp = g_string_new (NULL);
 		g_string_append_printf (tmp, "%sIP4_WINS_SERVERS=", prefix);
 		for (i = 0; i < wins->len; i++) {
-			struct in_addr addr;
-			char buf[INET_ADDRSTRLEN + 1];
-
-			addr.s_addr = g_array_index (wins, guint32, i);
-			memset (buf, 0, sizeof (buf));
-			if (inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
-				if (!first)
-					g_string_append_c (tmp, ' ');
-				g_string_append (tmp, buf);
-				first = FALSE;
-			}
+			guint32 addr;
+
+			addr = g_array_index (wins, guint32, i);
+			if (!first)
+				g_string_append_c (tmp, ' ');
+			g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL));
+			first = FALSE;
 		}
 		items = g_slist_prepend (items, tmp->str);
 		g_string_free (tmp, FALSE);
@@ -199,30 +182,19 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
 
 	for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) {
 		NMIP4Route *route = (NMIP4Route *) iter->data;
-		char str_addr[INET_ADDRSTRLEN + 1];
-		char str_nh[INET_ADDRSTRLEN + 1];
-		struct in_addr tmp_addr;
 		guint32 ip_prefix = nm_ip4_route_get_prefix (route);
 		guint32 metric = nm_ip4_route_get_metric (route);
 		char *routetmp;
 
-		memset (str_addr, 0, sizeof (str_addr));
-		tmp_addr.s_addr = nm_ip4_route_get_dest (route);
-		if (!inet_ntop (AF_INET, &tmp_addr, str_addr, sizeof (str_addr)))
-			continue;
+		nm_utils_inet4_ntop (nm_ip4_route_get_dest (route), str_addr);
+		nm_utils_inet4_ntop (nm_ip4_route_get_next_hop (route), str_gw);
 
-		memset (str_nh, 0, sizeof (str_nh));
-		tmp_addr.s_addr = nm_ip4_route_get_next_hop (route);
-		inet_ntop (AF_INET, &tmp_addr, str_nh, sizeof (str_nh));
-
-		routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_nh, metric);
+		routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric);
 		items = g_slist_prepend (items, routetmp);
 	}
 	items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, num));
-	if (routes) {
-		g_slist_foreach (routes, (GFunc) nm_ip4_route_unref, NULL);
-		g_slist_free (routes);
-	}
+	if (routes)
+		g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref);
 
 	return items;
 }
@@ -255,6 +227,8 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
 	guint32 num;
 	GString *tmp;
 	GValue *val;
+	char str_addr[INET6_ADDRSTRLEN];
+	char str_gw[INET6_ADDRSTRLEN];
 
 	if (ip6_config == NULL)
 		return items;
@@ -269,27 +243,19 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
 
 	for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) {
 		NMIP6Address *addr = (NMIP6Address *) iter->data;
-		char str_addr[INET6_ADDRSTRLEN];
-		char str_gw[INET6_ADDRSTRLEN];
-		const struct in6_addr *tmp_addr;
 		guint32 ip_prefix = nm_ip6_address_get_prefix (addr);
 		char *addrtmp;
 
-		tmp_addr = nm_ip6_address_get_address (addr);
-		inet_ntop (AF_INET6, tmp_addr, str_addr, sizeof (str_addr));
-
-		tmp_addr = nm_ip6_address_get_gateway (addr);
-		inet_ntop (AF_INET6, tmp_addr, str_gw, sizeof (str_gw));
+		nm_utils_inet6_ntop (nm_ip6_address_get_address (addr), str_addr);
+		nm_utils_inet6_ntop (nm_ip6_address_get_gateway (addr), str_gw);
 
 		addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw);
 		items = g_slist_prepend (items, addrtmp);
 	}
 	if (num)
 		items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, num));
-	if (addresses) {
-		g_slist_foreach (addresses, (GFunc) nm_ip6_address_unref, NULL);
-		g_slist_free (addresses);
-	}
+	if (addresses)
+		g_slist_free_full (addresses, (GDestroyNotify) nm_ip6_address_unref);
 
 	/* DNS servers */
 	val = g_hash_table_lookup (ip6_config, "nameservers");
@@ -297,23 +263,20 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
 		dns = nm_utils_ip6_dns_from_gvalue (val);
 
 	if (g_slist_length (dns)) {
+		gboolean first = TRUE;
+
 		tmp = g_string_new (NULL);
 		g_string_append_printf (tmp, "%sIP6_NAMESERVERS=", prefix);
 
 		for (iter = dns; iter; iter = g_slist_next (iter)) {
 			const struct in6_addr *addr = iter->data;
-			gboolean first = TRUE;
-			char buf[INET6_ADDRSTRLEN + 1];
-
-			memset (buf, 0, sizeof (buf));
-			if (inet_ntop (AF_INET6, addr, buf, sizeof (buf))) {
-				if (!first)
-					g_string_append_c (tmp, ' ');
-				g_string_append (tmp, buf);
-				first = FALSE;
-			}
+
+			if (!first)
+				g_string_append_c (tmp, ' ');
+			g_string_append (tmp, nm_utils_inet6_ntop (addr, NULL));
+			first = FALSE;
 		}
-	
+
 		items = g_slist_prepend (items, tmp->str);
 		g_string_free (tmp, FALSE);
 	}
@@ -328,31 +291,20 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
 
 	for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) {
 		NMIP6Route *route = (NMIP6Route *) iter->data;
-		char str_addr[INET6_ADDRSTRLEN + 1];
-		char str_nh[INET6_ADDRSTRLEN + 1];
-		const struct in6_addr *tmp_addr;
 		guint32 ip_prefix = nm_ip6_route_get_prefix (route);
 		guint32 metric = nm_ip6_route_get_metric (route);
 		char *routetmp;
 
-		memset (str_addr, 0, sizeof (str_addr));
-		tmp_addr = nm_ip6_route_get_dest (route);
-		if (!inet_ntop (AF_INET6, &tmp_addr, str_addr, sizeof (str_addr)))
-			continue;
+		nm_utils_inet6_ntop (nm_ip6_route_get_dest (route), str_addr);
+		nm_utils_inet6_ntop (nm_ip6_route_get_next_hop (route), str_gw);
 
-		memset (str_nh, 0, sizeof (str_nh));
-		tmp_addr = nm_ip6_route_get_next_hop (route);
-		inet_ntop (AF_INET6, &tmp_addr, str_nh, sizeof (str_nh));
-
-		routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_nh, metric);
+		routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric);
 		items = g_slist_prepend (items, routetmp);
 	}
 	if (num)
 		items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, num));
-	if (routes) {
-		g_slist_foreach (routes, (GFunc) nm_ip6_route_unref, NULL);
-		g_slist_free (routes);
-	}
+	if (routes)
+		g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref);
 
 	return items;
 }
@@ -393,10 +345,10 @@ nm_dispatcher_utils_construct_envp (const char *action,
                                     char **out_iface)
 {
 	const char *iface = NULL, *ip_iface = NULL;
-	const char *uuid = NULL, *id = NULL;
+	const char *uuid = NULL, *id = NULL, *path;
 	NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN;
 	GValue *value;
-	char **envp = NULL;
+	char **envp = NULL, *path_item;
 	GSList *items = NULL, *iter;
 	guint i;
 	GHashTable *con_setting_hash;
@@ -407,7 +359,7 @@ nm_dispatcher_utils_construct_envp (const char *action,
 
 	/* Hostname changes don't require a device nor contain a connection */
 	if (!strcmp (action, "hostname"))
-		return g_new0 (char *, 1);
+		goto done;
 
 	/* Canonicalize the VPN interface name; "" is used when passing it through
 	 * D-Bus so make sure that's fixed up here.
@@ -453,7 +405,7 @@ nm_dispatcher_utils_construct_envp (const char *action,
 			return NULL;
 		}
 		ip_iface = g_value_get_string (value);
-	}	
+	}
 
 	/* Device type */
 	value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_TYPE);
@@ -493,12 +445,6 @@ nm_dispatcher_utils_construct_envp (const char *action,
 		items = construct_ip6_items (items, vpn_ip6_props, "VPN_");
 	}
 
-	/* Convert the list to an environment pointer */
-	envp = g_new0 (char *, g_slist_length (items) + 1);
-	for (iter = items, i = 0; iter; iter = g_slist_next (iter), i++)
-		envp[i] = (char *) iter->data;
-	g_slist_free (items);
-
 	/* Backwards compat: 'iface' is set in this order:
 	 * 1) VPN interface name
 	 * 2) Device IP interface name
@@ -511,6 +457,19 @@ nm_dispatcher_utils_construct_envp (const char *action,
 	else
 		*out_iface = g_strdup (iface);
 
+ done:
+	path = g_getenv ("PATH");
+	if (path) {
+		path_item = g_strdup_printf ("PATH=%s", path);
+		items = g_slist_prepend (items, path_item);
+	}
+
+	/* Convert the list to an environment pointer */
+	envp = g_new0 (char *, g_slist_length (items) + 1);
+	for (iter = items, i = 0; iter; iter = g_slist_next (iter), i++)
+		envp[i] = (char *) iter->data;
+	g_slist_free (items);
+
 	return envp;
 }
 
diff --git a/callouts/nm-dispatcher-action.c b/callouts/nm-dispatcher.c
index de53f123..733af511 100644
--- a/callouts/nm-dispatcher-action.c
+++ b/callouts/nm-dispatcher.c
@@ -31,23 +31,27 @@
 #include <arpa/inet.h>
 
 #include <glib.h>
+#include <glib-unix.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
 
 
-#include "nm-dispatcher-action.h"
+#include "nm-dispatcher-api.h"
 #include "nm-dispatcher-utils.h"
-
-#define NMD_SCRIPT_DIR NMCONFDIR "/dispatcher.d"
+#include "nm-glib-compat.h"
 
 static GMainLoop *loop = NULL;
 static gboolean debug = FALSE;
 
+typedef struct Request Request;
+
 typedef struct {
 	GObject parent;
 
 	/* Private data */
+	Request *current_request;
+	GQueue *pending_requests;
 	guint quit_id;
 	gboolean persist;
 } Handler;
@@ -77,6 +81,7 @@ impl_dispatch (Handler *h,
                const char *vpn_ip_iface,
                GHashTable *vpn_ip4_props,
                GHashTable *vpn_ip6_props,
+               gboolean request_debug,
                DBusGMethodInvocation *context);
 
 #include "nm-dispatcher-glue.h"
@@ -92,8 +97,6 @@ handler_class_init (HandlerClass *h_class)
 {
 }
 
-typedef struct Request Request;
-
 static void dispatch_one_script (Request *request);
 
 typedef struct {
@@ -112,6 +115,8 @@ struct Request {
 	char *action;
 	char *iface;
 	char **envp;
+	gboolean debug;
+
 	GPtrArray *scripts;  /* list of ScriptInfo */
 	guint idx;
 
@@ -120,8 +125,10 @@ struct Request {
 };
 
 static void
-script_info_free (ScriptInfo *info)
+script_info_free (gpointer ptr)
 {
+	ScriptInfo *info = ptr;
+
 	g_free (info->script);
 	g_free (info->error);
 	g_free (info);
@@ -133,10 +140,8 @@ request_free (Request *request)
 	g_free (request->action);
 	g_free (request->iface);
 	g_strfreev (request->envp);
-	if (request->scripts) {
-		g_ptr_array_foreach (request->scripts, (GFunc) script_info_free, NULL);
+	if (request->scripts)
 		g_ptr_array_free (request->scripts, TRUE);
-	}
 }
 
 static gboolean
@@ -147,24 +152,57 @@ quit_timeout_cb (gpointer user_data)
 }
 
 static void
-quit_timeout_reschedule (Handler *h)
+quit_timeout_cancel (Handler *h)
 {
-	if (h->quit_id)
+	if (h->quit_id) {
 		g_source_remove (h->quit_id);
+		h->quit_id = 0;
+	}
+}
+
+static void
+quit_timeout_reschedule (Handler *h)
+{
+	quit_timeout_cancel (h);
 	if (!h->persist)
 		h->quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
 }
 
+static void
+start_request (Request *request)
+{
+	if (request->iface)
+		g_message ("Dispatching action '%s' for %s", request->action, request->iface);
+	else
+		g_message ("Dispatching action '%s'", request->action);
+
+	request->handler->current_request = request;
+	dispatch_one_script (request);
+}
+
+static void
+next_request (Handler *h)
+{
+	Request *request = g_queue_pop_head (h->pending_requests);
+
+	if (request) {
+		start_request (request);
+		return;
+	}
+
+	h->current_request = NULL;
+	quit_timeout_reschedule (h);
+}
+
 static gboolean
 next_script (gpointer user_data)
 {
 	Request *request = user_data;
+	Handler *h = request->handler;
 	GPtrArray *results;
 	GValueArray *item;
 	guint i;
 
-	quit_timeout_reschedule (request->handler);
-
 	request->idx++;
 	if (request->idx < request->scripts->len) {
 		dispatch_one_script (request);
@@ -175,7 +213,7 @@ next_script (gpointer user_data)
 	results = g_ptr_array_new_full (request->scripts->len, (GDestroyNotify) g_value_array_free);
 	for (i = 0; i < request->scripts->len; i++) {
 		ScriptInfo *script = g_ptr_array_index (request->scripts, i);
-		GValue elt = {0, };
+		GValue elt = G_VALUE_INIT;
 
 		item = g_value_array_new (3);
 
@@ -201,9 +239,17 @@ next_script (gpointer user_data)
 	}
 
 	dbus_g_method_return (request->context, results);
+	g_ptr_array_unref (results);
 
+	if (request->debug) {
+		if (request->iface)
+			g_message ("Dispatch '%s' on %s complete", request->action, request->iface);
+		else
+			g_message ("Dispatch '%s' complete", request->action);
+	}
 	request_free (request);
-	g_ptr_array_unref (results);
+
+	next_request (h);
 	return FALSE;
 }
 
@@ -238,7 +284,10 @@ script_watch_cb (GPid pid, gint status, gpointer user_data)
 		                                 script->script);
 	}
 
-	if (script->result != DISPATCH_RESULT_SUCCESS) {
+	if (script->result == DISPATCH_RESULT_SUCCESS) {
+		if (script->request->debug)
+			g_message ("Script '%s' complete", script->script);
+	} else {
 		script->result = DISPATCH_RESULT_FAILED;
 		g_warning ("%s", script->error);
 	}
@@ -271,33 +320,33 @@ script_timeout_cb (gpointer user_data)
 }
 
 static inline gboolean
-check_permissions (struct stat *s, GError **error)
+check_permissions (struct stat *s, const char **out_error_msg)
 {
 	g_return_val_if_fail (s != NULL, FALSE);
-	g_return_val_if_fail (error != NULL, FALSE);
-	g_return_val_if_fail (*error == NULL, FALSE);
+	g_return_val_if_fail (out_error_msg != NULL, FALSE);
+	g_return_val_if_fail (*out_error_msg == NULL, FALSE);
 
 	/* Only accept regular files */
 	if (!S_ISREG (s->st_mode)) {
-		g_set_error (error, 0, 0, "not a regular file.");
+		*out_error_msg = "not a regular file.";
 		return FALSE;
 	}
 
 	/* Only accept files owned by root */
 	if (s->st_uid != 0) {
-		g_set_error (error, 0, 0, "not owned by root.");
+		*out_error_msg = "not owned by root.";
 		return FALSE;
 	}
 
 	/* Only accept files not writable by group or other, and not SUID */
 	if (s->st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) {
-		g_set_error (error, 0, 0, "writable by group or other, or set-UID.");
+		*out_error_msg = "writable by group or other, or set-UID.";
 		return FALSE;
 	}
 
 	/* Only accept files executable by the owner */
 	if (!(s->st_mode & S_IXUSR)) {
-		g_set_error (error, 0, 0, "not executable by owner.");
+		*out_error_msg = "not executable by owner.";
 		return FALSE;
 	}
 
@@ -334,6 +383,8 @@ child_setup (gpointer user_data G_GNUC_UNUSED)
 	setpgid (pid, pid);
 }
 
+#define SCRIPT_TIMEOUT 600  /* 10 minutes */
+
 static void
 dispatch_one_script (Request *request)
 {
@@ -346,12 +397,12 @@ dispatch_one_script (Request *request)
 	argv[2] = request->action;
 	argv[3] = NULL;
 
-	if (debug)
-		g_message ("Script: %s %s %s", script->script, request->iface ? request->iface : "(none)", request->action);
+	if (request->debug)
+		g_message ("Running script '%s'", script->script);
 
 	if (g_spawn_async ("/", argv, request->envp, G_SPAWN_DO_NOT_REAP_CHILD, child_setup, request, &script->pid, &error)) {
 		request->script_watch_id = g_child_watch_add (script->pid, (GChildWatchFunc) script_watch_cb, script);
-		request->script_timeout_id = g_timeout_add_seconds (3, script_timeout_cb, script);
+		request->script_timeout_id = g_timeout_add_seconds (SCRIPT_TIMEOUT, script_timeout_cb, script);
 	} else {
 		g_warning ("Failed to execute script '%s': (%d) %s",
 		           script->script, error->code, error->message);
@@ -365,16 +416,26 @@ dispatch_one_script (Request *request)
 }
 
 static GSList *
-find_scripts (void)
+find_scripts (const char *str_action)
 {
 	GDir *dir;
 	const char *filename;
 	GSList *sorted = NULL;
 	GError *error = NULL;
-
-	if (!(dir = g_dir_open (NMD_SCRIPT_DIR, 0, &error))) {
-		g_warning ("Failed to open dispatcher directory '%s': (%d) %s",
-		           NMD_SCRIPT_DIR, error->code, error->message);
+	const char *dirname;
+
+	if (   strcmp (str_action, NMD_ACTION_PRE_UP) == 0
+	    || strcmp (str_action, NMD_ACTION_VPN_PRE_UP) == 0)
+		dirname = NMD_SCRIPT_DIR_PRE_UP;
+	else if (   strcmp (str_action, NMD_ACTION_PRE_DOWN) == 0
+	         || strcmp (str_action, NMD_ACTION_VPN_PRE_DOWN) == 0)
+		dirname = NMD_SCRIPT_DIR_PRE_DOWN;
+	else
+		dirname = NMD_SCRIPT_DIR_DEFAULT;
+
+	if (!(dir = g_dir_open (dirname, 0, &error))) {
+		g_message ("Failed to open dispatcher directory '%s': (%d) %s",
+		           dirname, error->code, error->message);
 		g_error_free (error);
 		return NULL;
 	}
@@ -383,22 +444,26 @@ find_scripts (void)
 		char *path;
 		struct stat	st;
 		int err;
+		const char *err_msg = NULL;
 
 		if (!check_filename (filename))
 			continue;
 
-		path = g_build_filename (NMD_SCRIPT_DIR, filename, NULL);
+		path = g_build_filename (dirname, filename, NULL);
 
 		err = stat (path, &st);
 		if (err)
 			g_warning ("Failed to stat '%s': %d", path, err);
-		else if (!check_permissions (&st, &error)) {
-			g_warning ("Cannot execute '%s': %s", path, error->message);
-			g_clear_error (&error);
-		} else {
+		else if (S_ISDIR (st.st_mode))
+			; /* silently skip. */
+		else if (!check_permissions (&st, &err_msg))
+			g_warning ("Cannot execute '%s': %s", path, err_msg);
+		else {
 			/* success */
 			sorted = g_slist_insert_sorted (sorted, path, (GCompareFunc) g_strcmp0);
+			path = NULL;
 		}
+		g_free (path);
 	}
 	g_dir_close (dir);
 
@@ -418,6 +483,7 @@ impl_dispatch (Handler *h,
                const char *vpn_ip_iface,
                GHashTable *vpn_ip4_props,
                GHashTable *vpn_ip6_props,
+               gboolean request_debug,
                DBusGMethodInvocation *context)
 {
 	GSList *sorted_scripts = NULL;
@@ -426,17 +492,18 @@ impl_dispatch (Handler *h,
 	char **p;
 	char *iface = NULL;
 
-	sorted_scripts = find_scripts ();
+	sorted_scripts = find_scripts (str_action);
 
 	if (!sorted_scripts) {
 		dbus_g_method_return (context, g_ptr_array_new ());
 		return;
 	}
 
-	quit_timeout_reschedule (h);
+	quit_timeout_cancel (h);
 
 	request = g_malloc0 (sizeof (*request));
 	request->handler = h;
+	request->debug = request_debug || debug;
 	request->context = context;
 	request->action = g_strdup (str_action);
 
@@ -453,7 +520,7 @@ impl_dispatch (Handler *h,
 	                                                    vpn_ip6_props,
 	                                                    &iface);
 
-	if (debug) {
+	if (request->debug) {
 		g_message ("------------ Action ID %p '%s' Interface %s Environment ------------",
 		           context, str_action, iface ? iface : "(none)");
 		for (p = request->envp; *p; p++)
@@ -463,7 +530,7 @@ impl_dispatch (Handler *h,
 
 	request->iface = g_strdup (iface);
 
-	request->scripts = g_ptr_array_sized_new (5);
+	request->scripts = g_ptr_array_new_full (5, script_info_free);
 	for (iter = sorted_scripts; iter; iter = g_slist_next (iter)) {
 		ScriptInfo *s = g_malloc0 (sizeof (*s));
 		s->request = request;
@@ -472,8 +539,10 @@ impl_dispatch (Handler *h,
 	}
 	g_slist_free (sorted_scripts);
 
-	/* start dispatching scripts */
-	dispatch_one_script (request);
+	if (h->current_request)
+		g_queue_push_tail (h->pending_requests, request);
+	else
+		start_request (request);
 }
 
 static void
@@ -596,27 +665,15 @@ logging_shutdown (void)
 	closelog ();
 }
 
-static void
-signal_handler (int signo)
+static gboolean
+signal_handler (gpointer user_data)
 {
-	if (signo == SIGINT || signo == SIGTERM) {
-		g_message ("Caught signal %d, shutting down...", signo);
-		g_main_loop_quit (loop);
-	}
-}
+	int signo = GPOINTER_TO_INT (user_data);
 
-static void
-setup_signals (void)
-{
-	struct sigaction action;
-	sigset_t mask;
-
-	sigemptyset (&mask);
-	action.sa_handler = signal_handler;
-	action.sa_mask = mask;
-	action.sa_flags = 0;
-	sigaction (SIGTERM,  &action, NULL);
-	sigaction (SIGINT,  &action, NULL);
+	g_message ("Caught signal %d, shutting down...", signo);
+	g_main_loop_quit (loop);
+
+	return G_SOURCE_REMOVE;
 }
 
 int
@@ -646,8 +703,12 @@ main (int argc, char **argv)
 
 	g_option_context_free (opt_ctx);
 
+#if !GLIB_CHECK_VERSION (2, 35, 0)
 	g_type_init ();
-	setup_signals ();
+#endif
+
+	g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM));
+	g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT));
 
 	if (!debug)
 		logging_setup ();
@@ -662,6 +723,7 @@ main (int argc, char **argv)
 	if (!handler)
 		return 1;
 	handler->persist = persist;
+	handler->pending_requests = g_queue_new ();
 
 	dbus_g_object_type_install_info (HANDLER_TYPE, &dbus_glib_nm_dispatcher_object_info);
 	dbus_g_connection_register_g_object (bus,
@@ -673,7 +735,9 @@ main (int argc, char **argv)
 
 	g_main_loop_run (loop);
 
+	g_queue_free (handler->pending_requests);
 	g_object_unref (handler);
+
 	dbus_g_connection_unref (bus);
 
 	if (!debug)
diff --git a/callouts/nm-dispatcher.xml b/callouts/nm-dispatcher.xml
index cba61508..1ae138b3 100644
--- a/callouts/nm-dispatcher.xml
+++ b/callouts/nm-dispatcher.xml
@@ -75,6 +75,12 @@
         </tp:docstring>
       </arg>
 
+      <arg name="debug" type="b" direction="in">
+        <tp:docstring>
+          Whether to log debug output.
+        </tp:docstring>
+      </arg>
+
       <arg name="results" type="a(sus)" direction="out">
         <tp:docstring>
           Results of dispatching operations.  Each element of the returned
diff --git a/callouts/org.freedesktop.nm_dispatcher.service.in b/callouts/org.freedesktop.nm_dispatcher.service.in
index 9feb3b46..ff037cca 100644
--- a/callouts/org.freedesktop.nm_dispatcher.service.in
+++ b/callouts/org.freedesktop.nm_dispatcher.service.in
@@ -1,6 +1,6 @@
 [D-BUS Service]
 Name=org.freedesktop.nm_dispatcher
-Exec=@libexecdir@/nm-dispatcher.action
+Exec=@libexecdir@/nm-dispatcher
 User=root
 SystemdService=dbus-org.freedesktop.nm-dispatcher.service
 
diff --git a/callouts/tests/Makefile.am b/callouts/tests/Makefile.am
index d33d0f91..de4b5f52 100644
--- a/callouts/tests/Makefile.am
+++ b/callouts/tests/Makefile.am
@@ -5,7 +5,10 @@ AM_CPPFLAGS = \
 	-I${top_builddir}/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_builddir)/libnm-util \
-	-I$(top_srcdir)/callouts
+	-I$(top_srcdir)/callouts \
+	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS)
 
 noinst_PROGRAMS = \
 	test-dispatcher-envp
@@ -15,11 +18,6 @@ noinst_PROGRAMS = \
 test_dispatcher_envp_SOURCES = \
 	test-dispatcher-envp.c
 
-test_dispatcher_envp_CPPFLAGS = \
-	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS) \
-	$(AM_CPPFLAGS)
-
 test_dispatcher_envp_LDADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(top_builddir)/callouts/libtest-dispatcher-envp.la \
diff --git a/callouts/tests/Makefile.in b/callouts/tests/Makefile.in
index c28aee5c..25255b59 100644
--- a/callouts/tests/Makefile.in
+++ b/callouts/tests/Makefile.in
@@ -83,7 +83,8 @@ subdir = callouts/tests
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
+	$(top_srcdir)/m4/compiler_warnings.m4 \
 	$(top_srcdir)/m4/gettext.m4 \
 	$(top_srcdir)/m4/gnome-code-coverage.m4 \
 	$(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \
@@ -103,7 +104,8 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 PROGRAMS = $(noinst_PROGRAMS)
 am__test_dispatcher_envp_SOURCES_DIST = test-dispatcher-envp.c
-@ENABLE_TESTS_TRUE@am_test_dispatcher_envp_OBJECTS = test_dispatcher_envp-test-dispatcher-envp.$(OBJEXT)
+@ENABLE_TESTS_TRUE@am_test_dispatcher_envp_OBJECTS =  \
+@ENABLE_TESTS_TRUE@	test-dispatcher-envp.$(OBJEXT)
 test_dispatcher_envp_OBJECTS = $(am_test_dispatcher_envp_OBJECTS)
 am__DEPENDENCIES_1 =
 @ENABLE_TESTS_TRUE@test_dispatcher_envp_DEPENDENCIES =  \
@@ -200,12 +202,15 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
+DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DHCLIENT_PATH = @DHCLIENT_PATH@
 DHCPCD_PATH = @DHCPCD_PATH@
+DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
 DSYMUTIL = @DSYMUTIL@
@@ -230,7 +235,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
 GNUTLS_LIBS = @GNUTLS_LIBS@
 GREP = @GREP@
 GTKDOC_CHECK = @GTKDOC_CHECK@
-GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
 GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
@@ -275,12 +279,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNDP_CFLAGS = @LIBNDP_CFLAGS@
+LIBNDP_LIBS = @LIBNDP_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
 LIBSOUP_LIBS = @LIBSOUP_LIBS@
+LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@
+LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -297,6 +305,8 @@ MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
+NEWT_CFLAGS = @NEWT_CFLAGS@
+NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
@@ -324,11 +334,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
+PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
 SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
@@ -343,6 +358,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
 UUID_CFLAGS = @UUID_CFLAGS@
 UUID_LIBS = @UUID_LIBS@
+VALGRIND_RULES = @VALGRIND_RULES@
 VAPIGEN = @VAPIGEN@
 VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@
 VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@
@@ -405,6 +421,7 @@ psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+subdirs = @subdirs@
 sysconfdir = @sysconfdir@
 systemdsystemunitdir = @systemdsystemunitdir@
 target_alias = @target_alias@
@@ -415,23 +432,22 @@ with_dhclient = @with_dhclient@
 with_dhcpcd = @with_dhcpcd@
 with_netconfig = @with_netconfig@
 with_resolvconf = @with_resolvconf@
+with_valgrind = @with_valgrind@
 @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/include \
 @ENABLE_TESTS_TRUE@	-I${top_builddir}/include \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/libnm-util \
 @ENABLE_TESTS_TRUE@	-I$(top_builddir)/libnm-util \
-@ENABLE_TESTS_TRUE@	-I$(top_srcdir)/callouts
+@ENABLE_TESTS_TRUE@	-I$(top_srcdir)/callouts \
+@ENABLE_TESTS_TRUE@	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+@ENABLE_TESTS_TRUE@	$(GLIB_CFLAGS) \
+@ENABLE_TESTS_TRUE@	$(DBUS_CFLAGS)
 
 
 ####### dispatcher envp #######
 @ENABLE_TESTS_TRUE@test_dispatcher_envp_SOURCES = \
 @ENABLE_TESTS_TRUE@	test-dispatcher-envp.c
 
-@ENABLE_TESTS_TRUE@test_dispatcher_envp_CPPFLAGS = \
-@ENABLE_TESTS_TRUE@	$(GLIB_CFLAGS) \
-@ENABLE_TESTS_TRUE@	$(DBUS_CFLAGS) \
-@ENABLE_TESTS_TRUE@	$(AM_CPPFLAGS)
-
 @ENABLE_TESTS_TRUE@test_dispatcher_envp_LDADD = \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-util/libnm-util.la \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/callouts/libtest-dispatcher-envp.la \
@@ -498,7 +514,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dispatcher-envp.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -521,20 +537,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
-test_dispatcher_envp-test-dispatcher-envp.o: test-dispatcher-envp.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dispatcher_envp-test-dispatcher-envp.o -MD -MP -MF $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o test_dispatcher_envp-test-dispatcher-envp.o `test -f 'test-dispatcher-envp.c' || echo '$(srcdir)/'`test-dispatcher-envp.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-dispatcher-envp.c' object='test_dispatcher_envp-test-dispatcher-envp.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dispatcher_envp-test-dispatcher-envp.o `test -f 'test-dispatcher-envp.c' || echo '$(srcdir)/'`test-dispatcher-envp.c
-
-test_dispatcher_envp-test-dispatcher-envp.obj: test-dispatcher-envp.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dispatcher_envp-test-dispatcher-envp.obj -MD -MP -MF $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'test-dispatcher-envp.c'; then $(CYGPATH_W) 'test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/test-dispatcher-envp.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo $(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-dispatcher-envp.c' object='test_dispatcher_envp-test-dispatcher-envp.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'test-dispatcher-envp.c'; then $(CYGPATH_W) 'test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/test-dispatcher-envp.c'; fi`
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/callouts/tests/dispatcher-old-down b/callouts/tests/dispatcher-old-down
index 6396287f..836f3532 100644
--- a/callouts/tests/dispatcher-old-down
+++ b/callouts/tests/dispatcher-old-down
@@ -12,6 +12,7 @@ interface=wlan0
 path=/org/freedesktop/NetworkManager/Devices/0
 
 [env]
+PATH=
 CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311
 CONNECTION_ID=Random Connection
 DEVICE_IFACE=wlan0
diff --git a/callouts/tests/dispatcher-old-up b/callouts/tests/dispatcher-old-up
index 76e3be8d..a35812ee 100644
--- a/callouts/tests/dispatcher-old-up
+++ b/callouts/tests/dispatcher-old-up
@@ -31,6 +31,7 @@ nameservers=68.87.77.134 68.87.72.134 192.168.1.1
 domains=hsd1.mn.comcast.net.
 
 [env]
+PATH=
 CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311
 CONNECTION_ID=Random Connection
 DEVICE_IFACE=wlan0
diff --git a/callouts/tests/dispatcher-old-vpn-down b/callouts/tests/dispatcher-old-vpn-down
index c11cbfd1..4fab5e95 100644
--- a/callouts/tests/dispatcher-old-vpn-down
+++ b/callouts/tests/dispatcher-old-vpn-down
@@ -31,6 +31,7 @@ nameservers=68.87.77.134 68.87.72.134 192.168.1.1
 domains=hsd1.mn.comcast.net.
 
 [env]
+PATH=
 CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e
 CONNECTION_ID=Random Connection
 DEVICE_IFACE=wlan0
diff --git a/callouts/tests/dispatcher-old-vpn-up b/callouts/tests/dispatcher-old-vpn-up
index ad47c91d..3c350dbf 100644
--- a/callouts/tests/dispatcher-old-vpn-up
+++ b/callouts/tests/dispatcher-old-vpn-up
@@ -31,6 +31,7 @@ nameservers=68.87.77.134 68.87.72.134 192.168.1.1
 domains=hsd1.mn.comcast.net.
 
 [env]
+PATH=
 CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e
 CONNECTION_ID=Random Connection
 DEVICE_IFACE=wlan0
diff --git a/callouts/tests/test-dispatcher-envp.c b/callouts/tests/test-dispatcher-envp.c
index 25b5f61d..a91ae2b2 100644
--- a/callouts/tests/test-dispatcher-envp.c
+++ b/callouts/tests/test-dispatcher-envp.c
@@ -29,7 +29,7 @@
 #include "nm-setting-connection.h"
 #include "nm-dispatcher-utils.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-dispatcher-action.h"
+#include "nm-dispatcher-api.h"
 #include "nm-utils.h"
 
 /*******************************************/
@@ -238,10 +238,10 @@ add_uint_array (GKeyFile *kf,
 		items = g_array_sized_new (FALSE, TRUE, sizeof (guint32), g_strv_length (split));
 		for (iter = split; iter && *iter; iter++) {
 			if (strlen (g_strstrip (*iter))) {
-				struct in_addr addr;
+				guint32 addr;
 
 				g_assert_cmpint (inet_pton (AF_INET, *iter, &addr), ==, 1);
-				g_array_append_val (items, addr.s_addr);
+				g_array_append_val (items, addr);
 			}
 		}
 		value_hash_add_uint_array (props, key, items);
@@ -294,7 +294,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 		list = NULL;
 		for (iter = split; iter && *iter; iter++) {
 			NMIP4Address *addr;
-			struct in_addr a;
+			guint32 a;
 			char *p;
 
 			if (strlen (g_strstrip (*iter)) == 0)
@@ -307,7 +307,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 			*p++ = '\0';
 
 			g_assert_cmpint (inet_pton (AF_INET, *iter, &a), ==, 1);
-			nm_ip4_address_set_address (addr, a.s_addr);
+			nm_ip4_address_set_address (addr, a);
 			nm_ip4_address_set_prefix (addr, (guint) atoi (p));
 
 			p = strchr (p, ' ');
@@ -315,7 +315,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 			p++;
 
 			g_assert_cmpint (inet_pton (AF_INET, p, &a), ==, 1);
-			nm_ip4_address_set_gateway (addr, a.s_addr);
+			nm_ip4_address_set_gateway (addr, a);
 
 			list = g_slist_append (list, addr);
 		}
@@ -338,7 +338,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 			list = NULL;
 			for (iter = split; iter && *iter; iter++) {
 				NMIP4Route *route;
-				struct in_addr a;
+				guint32 a;
 				char *p;
 
 				if (strlen (g_strstrip (*iter)) == 0)
@@ -351,7 +351,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 				*p++ = '\0';
 
 				g_assert_cmpint (inet_pton (AF_INET, *iter, &a), ==, 1);
-				nm_ip4_route_set_dest (route, a.s_addr);
+				nm_ip4_route_set_dest (route, a);
 				nm_ip4_route_set_prefix (route, (guint) atoi (p));
 
 				p = strchr (p, ' ');
@@ -359,7 +359,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
 				p++;
 
 				g_assert_cmpint (inet_pton (AF_INET, p, &a), ==, 1);
-				nm_ip4_route_set_next_hop (route, a.s_addr);
+				nm_ip4_route_set_next_hop (route, a);
 
 				p = strchr (p, ' ');
 				g_assert (p);
@@ -560,10 +560,18 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if
 	/* Compare dispatcher generated env and expected env */
 	for (iter = denv; iter && *iter; iter++) {
 		gpointer foo;
+		const char *i_value = *iter;
 
-		foo = g_hash_table_lookup (expected_env, *iter);
+		if (strstr (i_value, "PATH=") == i_value) {
+			g_assert_cmpstr (&i_value[strlen("PATH=")], ==, g_getenv ("PATH"));
+
+			/* The path is constructed dynamically. Ignore the actual value. */
+			i_value = "PATH=";
+		}
+
+		foo = g_hash_table_lookup (expected_env, i_value);
 		if (!foo)
-			g_warning ("Failed to find %s in environment", *iter);
+			g_warning ("Failed to find %s in environment", i_value);
 		g_assert (foo);
 	}
 
@@ -628,31 +636,23 @@ test_up_empty_vpn_iface (const char *path)
 
 /*******************************************/
 
-#if GLIB_CHECK_VERSION(2,25,12)
-typedef GTestFixtureFunc TCFunc;
-#else
-typedef void (*TCFunc)(void);
-#endif
-
-#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL)
-
-int main (int argc, char **argv)
+int
+main (int argc, char **argv)
 {
-	GTestSuite *suite;
-
 	g_assert (argc > 1);
 
 	g_test_init (&argc, &argv, NULL);
-	g_type_init ();
 
-	suite = g_test_get_root ();
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+	g_type_init ();
+#endif
 
-	g_test_suite_add (suite, TESTCASE (test_old_up, argv[1]));
-	g_test_suite_add (suite, TESTCASE (test_old_down, argv[1]));
-	g_test_suite_add (suite, TESTCASE (test_old_vpn_up, argv[1]));
-	g_test_suite_add (suite, TESTCASE (test_old_vpn_down, argv[1]));
+	g_test_add_data_func ("/dispatcher/old_up", argv[1], (GTestDataFunc) test_old_up);
+	g_test_add_data_func ("/dispatcher/old_down", argv[1], (GTestDataFunc) test_old_down);
+	g_test_add_data_func ("/dispatcher/old_vpn_up", argv[1], (GTestDataFunc) test_old_vpn_up);
+	g_test_add_data_func ("/dispatcher/old_vpn_down", argv[1], (GTestDataFunc) test_old_vpn_down);
 
-	g_test_suite_add (suite, TESTCASE (test_up_empty_vpn_iface, argv[1]));
+	g_test_add_data_func ("/dispatcher/up_empty_vpn_iface", argv[1], (GTestDataFunc) test_up_empty_vpn_iface);
 
 	return g_test_run ();
 }