diff options
Diffstat (limited to 'src')
169 files changed, 7370 insertions, 4526 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 808e59eb..a24ac6c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -229,6 +229,7 @@ nm_sources = \ rdisc/nm-lndp-rdisc.h \ rdisc/nm-rdisc.c \ rdisc/nm-rdisc.h \ + rdisc/nm-rdisc-private.h \ \ ppp-manager/nm-ppp-manager.c \ ppp-manager/nm-ppp-manager.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 6828f69c..da305209 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -17,7 +17,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -115,8 +125,6 @@ sbin_PROGRAMS = NetworkManager$(EXEEXT) libexec_PROGRAMS = nm-iface-helper$(EXEEXT) subdir = src -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -133,6 +141,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -182,11 +191,12 @@ am__libNetworkManager_la_SOURCES_DIST = devices/nm-device-bond.h \ platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ - ppp-manager/nm-ppp-manager.c ppp-manager/nm-ppp-manager.h \ - ppp-manager/nm-ppp-status.h settings/nm-agent-manager.c \ - settings/nm-agent-manager.h settings/nm-inotify-helper.c \ - settings/nm-inotify-helper.h settings/nm-secret-agent.c \ - settings/nm-secret-agent.h settings/nm-settings-connection.c \ + rdisc/nm-rdisc-private.h ppp-manager/nm-ppp-manager.c \ + ppp-manager/nm-ppp-manager.h ppp-manager/nm-ppp-status.h \ + settings/nm-agent-manager.c settings/nm-agent-manager.h \ + settings/nm-inotify-helper.c settings/nm-inotify-helper.h \ + settings/nm-secret-agent.c settings/nm-secret-agent.h \ + settings/nm-settings-connection.c \ settings/nm-settings-connection.h settings/nm-settings.c \ settings/nm-settings.h settings/nm-system-config-interface.c \ settings/nm-system-config-interface.h \ @@ -487,6 +497,8 @@ DIST_SUBDIRS = . devices/adsl devices/wifi dhcp-manager ppp-manager \ settings/plugins devices/wwan devices/bluetooth devices/wimax \ devices/team dhcp-manager/tests dnsmasq-manager/tests platform \ rdisc supplicant-manager/tests tests +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -538,7 +550,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -573,6 +584,7 @@ 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@ @@ -946,11 +958,12 @@ nm_sources = $(nm_device_headers) $(nm_dhcp_client_headers) \ platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ - ppp-manager/nm-ppp-manager.c ppp-manager/nm-ppp-manager.h \ - ppp-manager/nm-ppp-status.h settings/nm-agent-manager.c \ - settings/nm-agent-manager.h settings/nm-inotify-helper.c \ - settings/nm-inotify-helper.h settings/nm-secret-agent.c \ - settings/nm-secret-agent.h settings/nm-settings-connection.c \ + rdisc/nm-rdisc-private.h ppp-manager/nm-ppp-manager.c \ + ppp-manager/nm-ppp-manager.h ppp-manager/nm-ppp-status.h \ + settings/nm-agent-manager.c settings/nm-agent-manager.h \ + settings/nm-inotify-helper.c settings/nm-inotify-helper.h \ + settings/nm-secret-agent.c settings/nm-secret-agent.h \ + settings/nm-settings-connection.c \ settings/nm-settings-connection.h settings/nm-settings.c \ settings/nm-settings.h settings/nm-system-config-interface.c \ settings/nm-system-config-interface.h \ @@ -1121,7 +1134,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -1388,14 +1400,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -2351,6 +2363,8 @@ uninstall-am: uninstall-dbusserviceDATA uninstall-libexecPROGRAMS \ tags tags-am uninstall uninstall-am uninstall-dbusserviceDATA \ uninstall-libexecPROGRAMS uninstall-sbinPROGRAMS +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 2c291cdb..24cb949c 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -71,36 +71,36 @@ gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len) { - guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}; - guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */ - guchar first_octet; - - g_return_val_if_fail (addr != NULL, FALSE); - g_return_val_if_fail (len == ETH_ALEN || len == -1, FALSE); - - /* Compare the AP address the card has with invalid ethernet MAC addresses. */ - if (nm_utils_hwaddr_matches (addr, len, invalid_addr1, ETH_ALEN)) - return FALSE; + guint8 invalid_addr[4][ETH_ALEN] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, + {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}, /* prism54 dummy MAC */ + }; + guint8 addr_bin[ETH_ALEN]; + guint i; - if (nm_utils_hwaddr_matches (addr, len, invalid_addr2, ETH_ALEN)) + if (!addr) { + g_return_val_if_fail (len == -1 || len == ETH_ALEN, FALSE); return FALSE; + } - if (nm_utils_hwaddr_matches (addr, len, invalid_addr3, ETH_ALEN)) - return FALSE; + if (len == -1) { + if (!nm_utils_hwaddr_aton (addr, addr_bin, ETH_ALEN)) + return FALSE; + addr = addr_bin; + } else if (len != ETH_ALEN) + g_return_val_if_reached (FALSE); - if (nm_utils_hwaddr_matches (addr, len, invalid_addr4, ETH_ALEN)) + /* Check for multicast address */ + if ((((guint8 *) addr)[0]) & 0x01) return FALSE; - /* Check for multicast address */ - if (len == -1) - first_octet = strtoul (addr, NULL, 16); - else - first_octet = ((guint8 *)addr)[0]; - if (first_octet & 0x01) + for (i = 0; i < G_N_ELEMENTS (invalid_addr); i++) { + if (nm_utils_hwaddr_matches (addr, ETH_ALEN, invalid_addr[i], ETH_ALEN)) return FALSE; - + } + return TRUE; } @@ -152,27 +152,26 @@ nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_ int -nm_spawn_process (const char *args) +nm_spawn_process (const char *args, GError **error) { + GError *local = NULL; gint num_args; char **argv = NULL; int status = -1; - GError *error = NULL; g_return_val_if_fail (args != NULL, -1); + g_return_val_if_fail (!error || !*error, -1); - if (!g_shell_parse_argv (args, &num_args, &argv, &error)) { - nm_log_warn (LOGD_CORE, "could not parse arguments for '%s': %s", args, error->message); - g_error_free (error); - return -1; + if (g_shell_parse_argv (args, &num_args, &argv, &local)) { + g_spawn_sync ("/", argv, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &local); + g_strfreev (argv); } - if (!g_spawn_sync ("/", argv, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &error)) { - nm_log_warn (LOGD_CORE, "could not spawn process '%s': %s", args, error->message); - g_error_free (error); + if (local) { + nm_log_warn (LOGD_CORE, "could not spawn process '%s': %s", args, local->message); + g_propagate_error (error, local); } - g_strfreev (argv); return status; } @@ -814,6 +813,7 @@ const char *const NM_PATHS_DEFAULT[] = { "/sbin/", "/usr/sbin/", "/usr/local/sbin/", + "/bin/", "/usr/bin/", "/usr/local/bin/", NULL, @@ -1724,10 +1724,10 @@ nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max * Returns a variant3 UUID based on the concatenated C strings. * It does not simply concatenate them, but also includes the * terminating '\0' character. For example "a", "b", gives - * "a\0b\0\0". + * "a\0b\0". * * This has the advantage, that the following invocations - * all give different UUIDs: (""), ("",""), ("","a"), ("a",""), + * all give different UUIDs: (NULL), (""), ("",""), ("","a"), ("a",""), * ("aa"), ("aa", ""), ("", "aa"), ... */ char * @@ -2090,9 +2090,9 @@ nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, connection_diff_are_same = nm_connection_diff (connection, diff_base, NM_SETTING_COMPARE_FLAG_EXACT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, &connection_diff); if (connection_diff_are_same) { if (diff_base) - nm_log (level, domain, "%sconnection '%s' (%p and %p): no difference", prefix, name, connection, diff_base); + nm_log (level, domain, "%sconnection '%s' (%p/%s and %p/%s): no difference", prefix, name, connection, G_OBJECT_TYPE_NAME (connection), diff_base, G_OBJECT_TYPE_NAME (diff_base)); else - nm_log (level, domain, "%sconnection '%s' (%p): no properties set", prefix, name, connection); + nm_log (level, domain, "%sconnection '%s' (%p/%s): no properties set", prefix, name, connection, G_OBJECT_TYPE_NAME (connection)); g_assert (!connection_diff); return; } @@ -2127,9 +2127,9 @@ nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, GError *err_verify = NULL; if (diff_base) - nm_log (level, domain, "%sconnection '%s' (%p < %p):", prefix, name, connection, diff_base); + nm_log (level, domain, "%sconnection '%s' (%p/%s < %p/%s):", prefix, name, connection, G_OBJECT_TYPE_NAME (connection), diff_base, G_OBJECT_TYPE_NAME (diff_base)); else - nm_log (level, domain, "%sconnection '%s' (%p):", prefix, name, connection); + nm_log (level, domain, "%sconnection '%s' (%p/%s):", prefix, name, connection, G_OBJECT_TYPE_NAME (connection)); print_header = FALSE; if (!nm_connection_verify (connection, &err_verify)) { @@ -2312,6 +2312,7 @@ get_gre_eui64_u_bit (guint32 addr) * @link_type: the hardware link type * @hwaddr: the hardware address of the interface * @hwaddr_len: the length (in bytes) of @hwaddr + * @dev_id: the device identifier, if any * @out_iid: on success, filled with the interface identifier; on failure * zeroed out * @@ -2326,6 +2327,7 @@ gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, const guint8 *hwaddr, guint hwaddr_len, + guint dev_id, NMUtilsIPv6IfaceId *out_iid) { guint32 addr; @@ -2360,13 +2362,20 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, default: if (hwaddr_len == ETH_ALEN) { /* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See - * http://tools.ietf.org/html/rfc4291#appendix-A + * http://tools.ietf.org/html/rfc4291#appendix-A and the Linux + * kernel's net/ipv6/addrconf.c::ipv6_generate_eui64() function. */ - out_iid->id_u8[0] = hwaddr[0] ^ 0x02; + out_iid->id_u8[0] = hwaddr[0]; out_iid->id_u8[1] = hwaddr[1]; out_iid->id_u8[2] = hwaddr[2]; - out_iid->id_u8[3] = 0xff; - out_iid->id_u8[4] = 0xfe; + if (dev_id) { + out_iid->id_u8[3] = (dev_id >> 8) & 0xff; + out_iid->id_u8[4] = dev_id & 0xff; + } else { + out_iid->id_u8[0] ^= 0x02; + out_iid->id_u8[3] = 0xff; + out_iid->id_u8[4] = 0xfe; + } out_iid->id_u8[5] = hwaddr[3]; out_iid->id_u8[6] = hwaddr[4]; out_iid->id_u8[7] = hwaddr[5]; diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 40315c6e..ae1edd82 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -49,7 +49,7 @@ nm_utils_ip6_route_metric_normalize (guint32 metric) return metric ? metric : 1024 /*NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6*/; } -int nm_spawn_process (const char *args); +int nm_spawn_process (const char *args, GError **error); /* check if @flags has exactly one flag (@check) set. You should call this * only with @check being a compile time constant and a power of two. */ @@ -196,6 +196,7 @@ typedef struct { gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, const guint8 *hwaddr, guint len, + guint dev_id, NMUtilsIPv6IfaceId *out_iid); void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, diff --git a/src/devices/adsl/Makefile.in b/src/devices/adsl/Makefile.in index 7942c559..02da85e7 100644 --- a/src/devices/adsl/Makefile.in +++ b/src/devices/adsl/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/devices/adsl -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -207,6 +216,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -233,7 +244,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -268,6 +278,7 @@ 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@ @@ -524,7 +535,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/adsl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/adsl/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -596,14 +606,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -831,6 +841,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in index 0a285fda..b8e6dcda 100644 --- a/src/devices/bluetooth/Makefile.in +++ b/src/devices/bluetooth/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -85,8 +95,6 @@ host_triplet = @host@ @WITH_BLUEZ5_DUN_TRUE@am__append_3 = $(BLUEZ5_LIBS) subdir = src/devices/bluetooth -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -103,6 +111,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -227,6 +236,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -253,7 +264,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -288,6 +298,7 @@ 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@ @@ -536,7 +547,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/bluetooth/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/bluetooth/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -614,14 +624,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -849,6 +859,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 689f37c9..61371ddd 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -187,6 +187,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); @@ -929,7 +930,7 @@ bluez_device_removed (NMBluezDevice *bdev, gpointer user_data) /*****************************************************************************/ static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags) { NMDeviceBt *self = NM_DEVICE_BT (dev); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); @@ -957,7 +958,7 @@ handle_availability_change (NMDeviceBt *self, return; } - available = nm_device_is_available (device); + available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); if (available == old_available) return; @@ -987,7 +988,7 @@ set_mm_running (NMDeviceBt *self, gboolean running) _LOGD (LOGD_BT, "ModemManager now %s", running ? "available" : "unavailable"); - old_available = nm_device_is_available (NM_DEVICE (self)); + old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); priv->mm_running = running; handle_availability_change (self, old_available, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 9d9fe426..0b2c97d1 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -67,7 +67,7 @@ get_generic_capabilities (NMDevice *dev) } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags) { if (NM_DEVICE_GET_CLASS (dev)->is_up) return NM_DEVICE_GET_CLASS (dev)->is_up (dev); @@ -77,6 +77,7 @@ is_available (NMDevice *dev) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { /* Connections are always available because the carrier state is determined diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index a70cfd95..a2ed4b41 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -66,7 +66,7 @@ get_generic_capabilities (NMDevice *dev) } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags) { if (NM_DEVICE_GET_CLASS (dev)->is_up) return NM_DEVICE_GET_CLASS (dev)->is_up (dev); @@ -76,6 +76,7 @@ is_available (NMDevice *dev) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { /* Connections are always available because the carrier state is determined diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 65a9a71a..1f781bbc 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -33,7 +33,8 @@ enum NMActStageReturn { NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */ NM_ACT_STAGE_RETURN_POSTPONE, /* Long-running operation in progress */ NM_ACT_STAGE_RETURN_WAIT, /* Not ready to start stage; wait */ - NM_ACT_STAGE_RETURN_STOP /* Activation stage done; nothing to do */ + NM_ACT_STAGE_RETURN_STOP, /* Activation not wanted */ + NM_ACT_STAGE_RETURN_FINISH /* Activation stage done; nothing to do */ }; #define NM_DEVICE_CAP_NONSTANDARD_CARRIER 0x80000000 diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index a9899535..47526281 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -201,14 +201,18 @@ typedef struct { char * hw_addr; guint hw_addr_len; char * physical_port_id; + guint dev_id; NMUnmanagedFlags unmanaged_flags; gboolean is_nm_owned; /* whether the device is a device owned and created by NM */ DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */ + GCancellable *deactivating_cancellable; + guint32 ip4_address; NMActRequest * queued_act_request; + gboolean queued_act_request_is_waiting_for_carrier; NMActRequest * act_request; guint act_source_id; gpointer act_source_func; @@ -337,6 +341,8 @@ static gboolean addrconf6_start_with_link_ready (NMDevice *self); static gboolean dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection); static NMActStageReturn linklocal6_start (NMDevice *self); +static void _carrier_wait_check_queued_act_request (NMDevice *self); + static gboolean nm_device_get_default_unmanaged (NMDevice *self); static void _set_state_full (NMDevice *self, @@ -381,6 +387,7 @@ state_to_string (NMDeviceState state) } static const char *reason_table[] = { + [NM_DEVICE_STATE_REASON_UNKNOWN] = "unknown", [NM_DEVICE_STATE_REASON_NONE] = "none", [NM_DEVICE_STATE_REASON_NOW_MANAGED] = "managed", [NM_DEVICE_STATE_REASON_NOW_UNMANAGED] = "unmanaged", @@ -440,6 +447,7 @@ static const char *reason_table[] = { [NM_DEVICE_STATE_REASON_MODEM_FAILED] = "modem-failed", [NM_DEVICE_STATE_REASON_MODEM_AVAILABLE] = "modem-available", [NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT] = "sim-pin-incorrect", + [NM_DEVICE_STATE_REASON_NEW_ACTIVATION] = "new-activation", }; static const char * @@ -588,6 +596,7 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) static gboolean get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMLinkType link_type; const guint8 *hwaddr = NULL; size_t hwaddr_len = 0; @@ -608,6 +617,7 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) success = nm_utils_get_ipv6_interface_identifier (link_type, hwaddr, hwaddr_len, + priv->dev_id, out_iid); if (!success) { _LOGW (LOGD_HW, "failed to generate interface identifier " @@ -692,6 +702,8 @@ nm_device_get_priority (NMDevice *self) return 350; case NM_DEVICE_TYPE_VLAN: return 400; + case NM_DEVICE_TYPE_BRIDGE: + return 425; case NM_DEVICE_TYPE_MODEM: return 450; case NM_DEVICE_TYPE_BT: @@ -700,23 +712,37 @@ nm_device_get_priority (NMDevice *self) return 600; case NM_DEVICE_TYPE_OLPC_MESH: return 650; - default: + case NM_DEVICE_TYPE_GENERIC: return 950; + case NM_DEVICE_TYPE_UNKNOWN: + return 10000; + case NM_DEVICE_TYPE_UNUSED1: + case NM_DEVICE_TYPE_UNUSED2: + /* omit default: to get compiler warning about missing switch cases */ + break; } + return 11000; } guint32 nm_device_get_ip4_route_metric (NMDevice *self) { NMConnection *connection; + NMSettingIPConfig *s_ip = NULL; gint64 route_metric = -1; g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); connection = nm_device_get_connection (self); - if (connection) - route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (connection)); + s_ip = nm_connection_get_setting_ip4_config (connection); + + /* Slave interfaces don't have IP settings, but we may get here when + * external changes are made or when noticing IP changes when starting + * the slave connection. + */ + if (s_ip) + route_metric = nm_setting_ip_config_get_route_metric (s_ip); return route_metric >= 0 ? route_metric : nm_device_get_priority (self); } @@ -725,14 +751,21 @@ guint32 nm_device_get_ip6_route_metric (NMDevice *self) { NMConnection *connection; + NMSettingIPConfig *s_ip = NULL; gint64 route_metric = -1; g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); connection = nm_device_get_connection (self); - if (connection) - route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (connection)); + s_ip = nm_connection_get_setting_ip6_config (connection); + + /* Slave interfaces don't have IP settings, but we may get here when + * external changes are made or when noticing IP changes when starting + * the slave connection. + */ + if (s_ip) + route_metric = nm_setting_ip_config_get_route_metric (s_ip); return route_metric >= 0 ? route_metric : nm_device_get_priority (self); } @@ -1128,6 +1161,7 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier) g_source_remove (priv->carrier_wait_id); priv->carrier_wait_id = 0; nm_device_remove_pending_action (self, "carrier wait", TRUE); + _carrier_wait_check_queued_act_request (self); } } else if (state <= NM_DEVICE_STATE_DISCONNECTED) { _LOGI (LOGD_DEVICE, "link disconnected"); @@ -1717,16 +1751,24 @@ nm_device_removed (NMDevice *self) static gboolean -is_available (NMDevice *self) +is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - return priv->carrier || priv->ignore_carrier; + if (priv->carrier || priv->ignore_carrier) + return TRUE; + + if (NM_FLAGS_HAS (flags, NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER)) + return TRUE; + + return FALSE; } /** * nm_device_is_available: * @self: the #NMDevice + * @flags: additional flags to influence the check. Flags have the + * meaning to increase the availability of a device. * * Checks if @self would currently be capable of activating a * connection. In particular, it checks that the device is ready (eg, @@ -1742,14 +1784,14 @@ is_available (NMDevice *self) * Returns: %TRUE or %FALSE */ gboolean -nm_device_is_available (NMDevice *self) +nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->firmware_missing) return FALSE; - return NM_DEVICE_GET_CLASS (self)->is_available (self); + return NM_DEVICE_GET_CLASS (self)->is_available (self, flags); } gboolean @@ -1873,7 +1915,7 @@ can_auto_connect (NMDevice *self, if (!nm_setting_connection_get_autoconnect (s_con)) return FALSE; - return nm_device_connection_is_available (self, connection, FALSE); + return nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL); } /** @@ -3760,7 +3802,7 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) } /* success; already have the LL address; kick off DHCP */ - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH); } if (!dhcp6_start_with_link_ready (self, connection)) { @@ -3925,7 +3967,7 @@ linklocal6_start (NMDevice *self) linklocal6_cleanup (self); if (have_ip6_address (priv->ip6_config, TRUE)) - return NM_ACT_STAGE_RETURN_SUCCESS; + return NM_ACT_STAGE_RETURN_FINISH; connection = nm_device_get_connection (self); g_assert (connection); @@ -4126,14 +4168,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) } } - /* hop_limit == 0 is a special value "unspecified", so do not touch - * in this case */ - if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) { - char val[16]; - - g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit); - nm_device_ipv6_sysctl_set (self, "hop_limit", val); - } + if (changed & NM_RDISC_CONFIG_HOP_LIMIT) + nm_platform_sysctl_set_ip6_hop_limit_safe (nm_device_get_ip_iface (self), rdisc->hop_limit); if (changed & NM_RDISC_CONFIG_MTU) { char val[16]; @@ -4241,7 +4277,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) } /* success; already have the LL address; kick off router discovery */ - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH); return addrconf6_start_with_link_ready (self); } @@ -4345,11 +4381,12 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) if (enable) { /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ value = nm_platform_sysctl_get (nm_utils_ip6_property_path (iface, "disable_ipv6")); - if (g_strcmp0 (value, "0") == 0) { + if (g_strcmp0 (value, "0") == 0) nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); - nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); - } g_free (value); + + /* Ensure IPv6 is enabled */ + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); } } @@ -4445,7 +4482,7 @@ act_stage3_ip6_config_start (NMDevice *self, connection = nm_device_get_connection (self); g_assert (connection); - if ( connection_ip4_method_requires_carrier (connection, NULL) + if ( connection_ip6_method_requires_carrier (connection, NULL) && priv->is_master && !priv->carrier) { _LOGI (LOGD_IP6 | LOGD_DEVICE, @@ -4519,7 +4556,7 @@ act_stage3_ip6_config_start (NMDevice *self, ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { ret = linklocal6_start (self); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + if (ret == NM_ACT_STAGE_RETURN_FINISH) { /* New blank config; LL address is already in priv->ext_ip6_config */ *out_config = nm_ip6_config_new (); g_assert (*out_config); @@ -4626,8 +4663,13 @@ nm_device_activate_stage3_ip6_start (NMDevice *self) nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); return FALSE; } else if (ret == NM_ACT_STAGE_RETURN_STOP) { - /* Early finish */ + /* Activation not wanted */ priv->ip6_state = IP_FAIL; + } else if (ret == NM_ACT_STAGE_RETURN_FINISH) { + /* Early finish, nothing more to do */ + priv->ip6_state = IP_DONE; + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); } else if (ret == NM_ACT_STAGE_RETURN_WAIT) { /* Wait for something to try IP config again */ priv->ip6_state = IP_WAIT; @@ -5569,6 +5611,15 @@ disconnect_cb (NMDevice *self, } static void +_clear_queued_act_request (NMDevicePrivate *priv) +{ + if (priv->queued_act_request) { + nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED); + g_clear_object (&priv->queued_act_request); + } +} + +static void impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context) { NMConnection *connection; @@ -5670,26 +5721,97 @@ _device_activate (NMDevice *self, NMActRequest *req) nm_device_activate_schedule_stage1_device_prepare (self); } +static void +_carrier_wait_check_queued_act_request (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMActRequest *queued_req; + + if ( !priv->queued_act_request + || !priv->queued_act_request_is_waiting_for_carrier) + return; + + priv->queued_act_request_is_waiting_for_carrier = FALSE; + if (!priv->carrier) { + _LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout"); + g_clear_object (&priv->queued_act_request); + } else { + _LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier"); + queued_req = priv->queued_act_request; + priv->queued_act_request = NULL; + _device_activate (self, queued_req); + g_object_unref (queued_req); + } +} + +static gboolean +_carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + + /* If we have carrier or if we are not waiting for it, the activation + * request is not blocked waiting for carrier. */ + if (priv->carrier) + return FALSE; + if (priv->carrier_wait_id == 0) + return FALSE; + + connection = nm_act_request_get_connection (req); + + if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) { + /* We passed all @flags we have, and no @specific_object. + * This equals maximal availability, if a connection is not available + * in this case, it is not waiting for carrier. + * + * Actually, why are we even trying to activate it? Strange, but whatever + * the reason, don't wait for carrier. + */ + return FALSE; + } + + if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, NULL)) { + /* The connection was available with flags ALL, and it is still available + * if we pretend not to wait for carrier. That means that the + * connection is available now, and does not wait for carrier. + * + * Since the flags increase the availability of a connection, when checking + * ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */ + return FALSE; + } + + /* The activation request must wait for carrier. */ + return TRUE; +} + void nm_device_queue_activation (NMDevice *self, NMActRequest *req) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean must_queue; + + must_queue = _carrier_wait_check_act_request_must_queue (self, req); - if (!priv->act_request) { + if (!priv->act_request && !must_queue) { /* Just activate immediately */ _device_activate (self, req); return; } /* supercede any already-queued request */ - g_clear_object (&priv->queued_act_request); + _clear_queued_act_request (priv); priv->queued_act_request = g_object_ref (req); + priv->queued_act_request_is_waiting_for_carrier = must_queue; - /* Deactivate existing activation request first */ - _LOGI (LOGD_DEVICE, "disconnecting for new activation request."); - nm_device_state_changed (self, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_NONE); + _LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect"); + + if (priv->act_request) { + /* Deactivate existing activation request first */ + _LOGI (LOGD_DEVICE, "disconnecting for new activation request."); + nm_device_state_changed (self, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_NEW_ACTIVATION); + } } /* @@ -5915,7 +6037,7 @@ nm_device_set_ip6_config (NMDevice *self, nm_ip6_config_export (new_config); } - _LOGD (LOGD_IP4, "set IP6Config instance (%s)", + _LOGD (LOGD_IP6, "set IP6Config instance (%s)", nm_ip6_config_get_dbus_path (new_config)); } } else if (old_config) { @@ -6231,6 +6353,9 @@ carrier_wait_timeout (gpointer user_data) NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0; nm_device_remove_pending_action (self, "carrier wait", TRUE); + + _carrier_wait_check_queued_act_request (self); + return G_SOURCE_REMOVE; } @@ -6295,12 +6420,11 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) * a timeout is reached. */ if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - if (priv->carrier_wait_id) { + if (priv->carrier_wait_id) g_source_remove (priv->carrier_wait_id); - nm_device_remove_pending_action (self, "carrier wait", TRUE); - } + else + nm_device_add_pending_action (self, "carrier wait", TRUE); priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self); - nm_device_add_pending_action (self, "carrier wait", TRUE); } /* Can only get HW address of some devices when they are up */ @@ -6728,12 +6852,12 @@ nm_device_set_unmanaged_quitting (NMDevice *self) /* It's OK to block here because we're quitting */ if (nm_device_is_activating (self) || priv->state == NM_DEVICE_STATE_ACTIVATED) - _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE); + _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NOW_UNMANAGED, TRUE); nm_device_set_unmanaged (self, NM_UNMANAGED_INTERNAL, TRUE, - NM_DEVICE_STATE_REASON_REMOVED); + NM_DEVICE_STATE_REASON_NOW_UNMANAGED); } /** @@ -6788,48 +6912,45 @@ nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) } /** - * nm_device_connection_is_available(): + * nm_device_check_connection_available(): * @self: the #NMDevice * @connection: the #NMConnection to check for availability - * @allow_device_override: set to %TRUE to let the device do specific checks + * @flags: flags to affect the decision making of whether a connection + * is available. Adding a flag can only make a connection more available, + * not less. + * @specific_object: a device type dependent argument to further + * filter the result. Passing a non %NULL specific object can only reduce + * the availability of a connection. * - * Check if @connection is available to be activated on @self. Normally this - * only checks if the connection is in @self's AvailableConnections property. - * If @allow_device_override is %TRUE then the device is asked to do specific - * checks that may bypass the AvailableConnections property. + * Check if @connection is available to be activated on @self. * * Returns: %TRUE if @connection can be activated on @self */ gboolean -nm_device_connection_is_available (NMDevice *self, - NMConnection *connection, - gboolean allow_device_override) +nm_device_check_connection_available (NMDevice *self, + NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, + const char *specific_object) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean available = FALSE; + NMDeviceState state; - if (nm_device_get_default_unmanaged (self) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { - /* default-unmanaged devices in UNMANAGED state have no available connections - * so we must manually check whether the connection is available here. - */ - if ( nm_device_check_connection_compatible (self, connection) - && NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) - return TRUE; - } + state = nm_device_get_state (self); + if (state < NM_DEVICE_STATE_UNMANAGED) + return FALSE; + if ( state < NM_DEVICE_STATE_UNAVAILABLE + && nm_device_get_unmanaged_flag (self, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT)) + return FALSE; + if ( state < NM_DEVICE_STATE_DISCONNECTED + && ( ( !NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER) + && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) + || ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER) + && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER)))) + return FALSE; - available = !!g_hash_table_lookup (priv->available_connections, connection); - if (!available && allow_device_override) { - /* FIXME: hack for hidden WiFi becuase clients didn't consistently - * set the 'hidden' property to indicate hidden SSID networks. If - * activating but the network isn't available let the device recheck - * availability. - */ - if ( nm_device_check_connection_compatible (self, connection) - && NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden) - available = NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden (self, connection); - } + if (!nm_device_check_connection_compatible (self, connection)) + return FALSE; - return available; + return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object); } static void @@ -6849,17 +6970,10 @@ _clear_available_connections (NMDevice *self, gboolean do_signal) static gboolean _try_add_available_connection (NMDevice *self, NMConnection *connection) { - if ( nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED - && !nm_device_get_default_unmanaged (self)) - return FALSE; - - if (nm_device_check_connection_compatible (self, connection)) { - if (NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) { - g_hash_table_insert (NM_DEVICE_GET_PRIVATE (self)->available_connections, - g_object_ref (connection), - GUINT_TO_POINTER (1)); - return TRUE; - } + if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL)) { + g_hash_table_add (NM_DEVICE_GET_PRIVATE (self)->available_connections, + g_object_ref (connection)); + return TRUE; } return FALSE; } @@ -6873,15 +6987,28 @@ _del_available_connection (NMDevice *self, NMConnection *connection) static gboolean check_connection_available (NMDevice *self, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + /* Connections which require a network connection are not available when * the device has no carrier, even with ignore-carrer=TRUE. */ - if (NM_DEVICE_GET_PRIVATE (self)->carrier == FALSE) - return connection_requires_carrier (connection) ? FALSE : TRUE; + if ( priv->carrier + || !connection_requires_carrier (connection)) + return TRUE; - return TRUE; + if ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER) + && priv->carrier_wait_id != 0) { + /* The device has no carrier though the connection requires it. + * + * If we are still waiting for carrier, the connection is available + * for an explicit user-request. */ + return TRUE; + } + + return FALSE; } void @@ -6933,8 +7060,8 @@ nm_device_get_available_connections (NMDevice *self, const char *specific_object /* If a specific object is given, only include connections that are * compatible with it. */ - if ( !specific_object - || NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, specific_object)) + if ( !specific_object /* << Optimization: we know that the connection is available without @specific_object. */ + || nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, specific_object)) g_ptr_array_add (array, connection); } } @@ -7190,7 +7317,7 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure) * */ static void -nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) +nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, gboolean deconfigure) { NMDevicePrivate *priv; int ifindex; @@ -7205,12 +7332,14 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) /* Save whether or not we tried IPv6 for later */ priv = NM_DEVICE_GET_PRIVATE (self); - _cleanup_generic_pre (self, TRUE); + _cleanup_generic_pre (self, deconfigure); /* Turn off kernel IPv6 */ - set_disable_ipv6 (self, "1"); - nm_device_ipv6_sysctl_set (self, "accept_ra", "0"); - nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); + if (deconfigure) { + set_disable_ipv6 (self, "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra", "0"); + nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); + } /* Call device type-specific deactivation */ if (NM_DEVICE_GET_CLASS (self)->deactivate) @@ -7231,7 +7360,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) nm_platform_address_flush (ifindex); } - _cleanup_generic_post (self, TRUE); + _cleanup_generic_post (self, deconfigure); } static char * @@ -7332,7 +7461,7 @@ nm_device_spawn_iface_helper (NMDevice *self) } hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client); - if (client_id) { + if (hostname) { g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); g_ptr_array_add (argv, g_strdup (hostname)); } @@ -7430,6 +7559,69 @@ ip6_managed_setup (NMDevice *self) } static void +deactivate_async_ready (NMDevice *self, + GAsyncResult *res, + gpointer user_data) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceStateReason reason = GPOINTER_TO_UINT (user_data); + GError *error = NULL; + + NM_DEVICE_GET_CLASS (self)->deactivate_async_finish (self, res, &error); + + /* If operation cancelled, just return */ + if ( g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) + || (priv->deactivating_cancellable && g_cancellable_is_cancelled (priv->deactivating_cancellable))) { + nm_log_warn (LOGD_DEVICE, "Deactivation (%s) cancelled", + nm_device_get_iface (self)); + } + /* In every other case, transition to the DISCONNECTED state */ + else { + if (error) + nm_log_warn (LOGD_DEVICE, "Deactivation (%s) failed: %s", + nm_device_get_iface (self), + error->message); + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason); + } + + g_clear_object (&priv->deactivating_cancellable); + g_clear_error (&error); +} + +static void +deactivate_dispatcher_complete (guint call_id, gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceStateReason reason; + + g_return_if_fail (call_id == priv->dispatcher.call_id); + g_return_if_fail (priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED); + + reason = priv->dispatcher.post_state_reason; + + priv->dispatcher.call_id = 0; + priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; + priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; + + if (priv->deactivating_cancellable) { + g_warn_if_reached (); + g_cancellable_cancel (priv->deactivating_cancellable); + g_clear_object (&priv->deactivating_cancellable); + } + + if ( NM_DEVICE_GET_CLASS (self)->deactivate_async + && NM_DEVICE_GET_CLASS (self)->deactivate_async_finish) { + priv->deactivating_cancellable = g_cancellable_new (); + NM_DEVICE_GET_CLASS (self)->deactivate_async (self, + priv->deactivating_cancellable, + (GAsyncReadyCallback) deactivate_async_ready, + GUINT_TO_POINTER (reason)); + } else + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason); +} + +static void _set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, @@ -7473,13 +7665,15 @@ _set_state_full (NMDevice *self, nm_device_queued_state_clear (self); dispatcher_cleanup (self); + if (priv->deactivating_cancellable) + g_cancellable_cancel (priv->deactivating_cancellable); /* Cache the activation request for the dispatcher */ req = priv->act_request ? g_object_ref (priv->act_request) : NULL; if (state <= NM_DEVICE_STATE_UNAVAILABLE) { _clear_available_connections (self, TRUE); - g_clear_object (&priv->queued_act_request); + _clear_queued_act_request (priv); } /* Update the available connections list when a device first becomes available */ @@ -7494,12 +7688,16 @@ _set_state_full (NMDevice *self, case NM_DEVICE_STATE_UNMANAGED: nm_device_set_firmware_missing (self, FALSE); if (old_state > NM_DEVICE_STATE_UNMANAGED) { - /* Clean up if the device is now unmanaged but was activated */ - if (nm_device_get_act_request (self)) - nm_device_cleanup (self, reason); - nm_device_take_down (self, TRUE); - set_nm_ipv6ll (self, FALSE); - restore_ip6_properties (self); + if (reason == NM_DEVICE_STATE_REASON_REMOVED) { + nm_device_cleanup (self, reason, FALSE); + } else { + /* Clean up if the device is now unmanaged but was activated */ + if (nm_device_get_act_request (self)) + nm_device_cleanup (self, reason, TRUE); + nm_device_take_down (self, TRUE); + set_nm_ipv6ll (self, FALSE); + restore_ip6_properties (self); + } } break; case NM_DEVICE_STATE_UNAVAILABLE: @@ -7524,7 +7722,7 @@ _set_state_full (NMDevice *self, * Note that we "deactivate" the device even when coming from * UNMANAGED, to ensure that it's in a clean state. */ - nm_device_cleanup (self, reason); + nm_device_cleanup (self, reason, TRUE); } break; case NM_DEVICE_STATE_DISCONNECTED: @@ -7534,7 +7732,7 @@ _set_state_full (NMDevice *self, */ set_nm_ipv6ll (self, TRUE); - nm_device_cleanup (self, reason); + nm_device_cleanup (self, reason, TRUE); } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { /* Ensure IPv6 is set up as it may not have been done when @@ -7575,7 +7773,7 @@ _set_state_full (NMDevice *self, * we can't change states again from the state handler for a variety of * reasons. */ - if (nm_device_is_available (self)) { + if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { _LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED"); nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); } else { @@ -7597,16 +7795,17 @@ _set_state_full (NMDevice *self, if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN, nm_act_request_get_connection (req), self, - dispatcher_complete_proceed_state, + deactivate_dispatcher_complete, self, &priv->dispatcher.call_id)) { /* Just proceed on errors */ - dispatcher_complete_proceed_state (0, self); + deactivate_dispatcher_complete (0, self); } } break; case NM_DEVICE_STATE_DISCONNECTED: - if (priv->queued_act_request) { + if ( priv->queued_act_request + && !priv->queued_act_request_is_waiting_for_carrier) { NMActRequest *queued_req; queued_req = priv->queued_act_request; @@ -8057,6 +8256,9 @@ constructor (GType type, g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self); + /* trigger initial ip config change to initialize ip-config */ + priv->queued_ip_config_id = g_idle_add (queued_ip_config_change, self); + if (nm_platform_check_support_user_ipv6ll ()) { int ip_ifindex = nm_device_get_ip_ifindex (self); @@ -8103,6 +8305,7 @@ constructed (GObject *object) if (priv->ifindex > 0) { priv->is_software = nm_platform_link_is_software (priv->ifindex); priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex); + priv->dev_id = nm_platform_link_get_dev_id (priv->ifindex); priv->mtu = nm_platform_link_get_mtu (priv->ifindex); } /* Indicate software device in capabilities. */ @@ -8164,7 +8367,7 @@ dispose (GObject *object) _cleanup_generic_post (self, FALSE); - g_clear_pointer (&priv->ip6_saved_properties, g_hash_table_unref); + g_hash_table_remove_all (priv->ip6_saved_properties); if (priv->recheck_assume_id) { g_source_remove (priv->recheck_assume_id); @@ -8180,15 +8383,14 @@ dispose (GObject *object) priv->con_provider = NULL; } - g_hash_table_unref (priv->available_connections); - priv->available_connections = NULL; + g_hash_table_remove_all (priv->available_connections); if (priv->carrier_wait_id) { g_source_remove (priv->carrier_wait_id); priv->carrier_wait_id = 0; } - g_clear_object (&priv->queued_act_request); + _clear_queued_act_request (priv); platform = nm_platform_get (); g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self); @@ -8218,6 +8420,9 @@ finalize (GObject *object) g_free (priv->type_desc); g_free (priv->dhcp_anycast_address); + g_hash_table_unref (priv->ip6_saved_properties); + g_hash_table_unref (priv->available_connections); + G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index b3855c74..e204af84 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -23,6 +23,7 @@ #define __NETWORKMANAGER_DEVICE_H__ #include <glib-object.h> +#include <gio/gio.h> #include <dbus/dbus-glib.h> #include <netinet/in.h> @@ -85,10 +86,37 @@ G_BEGIN_DECLS typedef enum NMActStageReturn NMActStageReturn; +/* These flags affect whether a connection is considered available on a device + * (check_connection_available()). The flags should have the meaning of relaxing + * a condition, so that adding a flag might make a connection available that would + * not be available otherwise. Adding a flag should never make a connection + * not available if it would be available otherwise. */ +typedef enum { /*< skip >*/ + NM_DEVICE_CHECK_CON_AVAILABLE_NONE = 0, + + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER = (1L << 0), + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP = (1L << 1), + NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER + | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP, + + __NM_DEVICE_CHECK_CON_AVAILABLE_ALL, + NM_DEVICE_CHECK_CON_AVAILABLE_ALL = (((__NM_DEVICE_CHECK_CON_AVAILABLE_ALL - 1) << 1) - 1), +} NMDeviceCheckConAvailableFlags; + struct _NMDevice { GObject parent; }; +/* The flags have an relaxing meaning, that means, specifying more flags, can make + * a device appear more available. It can never make a device less available. */ +typedef enum { /*< skip >*/ + NM_DEVICE_CHECK_DEV_AVAILABLE_NONE = 0, + NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER = (1L << 0), + + __NM_DEVICE_CHECK_DEV_AVAILABLE_ALL, + NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (((__NM_DEVICE_CHECK_DEV_AVAILABLE_ALL - 1) << 1) - 1), +} NMDeviceCheckDevAvailableFlags; + typedef struct { GObjectClass parent; @@ -116,7 +144,7 @@ typedef struct { guint32 (* get_generic_capabilities) (NMDevice *self); - gboolean (* is_available) (NMDevice *self); + gboolean (* is_available) (NMDevice *self, NMDeviceCheckDevAvailableFlags flags); gboolean (* get_enabled) (NMDevice *self); @@ -136,19 +164,18 @@ typedef struct { * including any live network information like scan lists. The connection * is checked against the object defined by @specific_object, if given. * Returns TRUE if the connection is available; FALSE if not. + * + * The passed @flags affect whether a connection is considered + * available or not. Adding more flags, means the connection is + * *more* available. + * + * Specifying @specific_object can only reduce the availability of a connection. */ gboolean (* check_connection_available) (NMDevice *self, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object); - /* Same as check_connection_available() but called if the connection - * is not present in the activating-connections array during activation, - * to give the device a chance to allow/deny the activation. This is a - * hack only meant for hidden WiFi networks. - */ - gboolean (* check_connection_available_wifi_hidden) (NMDevice *self, - NMConnection *connection); - gboolean (* complete_connection) (NMDevice *self, NMConnection *connection, const char *specific_object, @@ -174,6 +201,16 @@ typedef struct { void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config); void (* ip6_config_pre_commit) (NMDevice *self, NMIP6Config *config); + /* Async deactivating (in the DEACTIVATING phase) */ + void (* deactivate_async) (NMDevice *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* deactivate_async_finish) (NMDevice *self, + GAsyncResult *res, + GError **error); + + /* Sync deactivating (in the DISCONNECTED phase) */ void (* deactivate) (NMDevice *self); gboolean (* spec_match_list) (NMDevice *self, const GSList *specs); @@ -257,7 +294,7 @@ NMConnection * nm_device_get_connection (NMDevice *dev); void nm_device_removed (NMDevice *dev); -gboolean nm_device_is_available (NMDevice *dev); +gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags); gboolean nm_device_has_carrier (NMDevice *dev); NMConnection * nm_device_generate_connection (NMDevice *self, NMDevice *master); @@ -316,7 +353,8 @@ typedef enum { /* Boundary value */ __NM_UNMANAGED_LAST, - NM_UNMANAGED_LAST = __NM_UNMANAGED_LAST - 1, + NM_UNMANAGED_LAST = __NM_UNMANAGED_LAST - 1, + NM_UNMANAGED_ALL = ((NM_UNMANAGED_LAST << 1) - 1), } NMUnmanagedFlags; gboolean nm_device_get_managed (NMDevice *device); @@ -360,9 +398,10 @@ gboolean nm_device_has_pending_action (NMDevice *device); GPtrArray *nm_device_get_available_connections (NMDevice *device, const char *specific_object); -gboolean nm_device_connection_is_available (NMDevice *device, - NMConnection *connection, - gboolean allow_device_override); +gboolean nm_device_check_connection_available (NMDevice *device, + NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, + const char *specific_object); gboolean nm_device_notify_component_added (NMDevice *device, GObject *component); diff --git a/src/devices/team/Makefile.in b/src/devices/team/Makefile.in index 4ee30e66..29ad0598 100644 --- a/src/devices/team/Makefile.in +++ b/src/devices/team/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ @WITH_TEAMDCTL_TRUE@am__append_1 = ${LIBTEAMDCTL_CFLAGS} @WITH_TEAMDCTL_TRUE@am__append_2 = $(LIBTEAMDCTL_LIBS) subdir = src/devices/team -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -211,6 +220,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -237,7 +248,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -272,6 +282,7 @@ 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@ @@ -523,7 +534,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/team/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/team/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -595,14 +605,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -830,6 +840,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 16f1fcc2..49202c36 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -41,6 +41,7 @@ #include "nm-team-enum-types.h" #include "nm-posix-signals.h" #include "nm-core-internal.h" +#include "gsystem-local-alloc.h" #include "nm-device-team-glue.h" @@ -51,8 +52,6 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) #define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) -static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); - typedef struct { struct teamdctl *tdc; GPid teamd_pid; @@ -68,6 +67,8 @@ enum { LAST_PROP }; +static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); + /******************************************************************/ static guint32 @@ -77,7 +78,7 @@ get_generic_capabilities (NMDevice *device) } static gboolean -is_available (NMDevice *device) +is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { if (NM_DEVICE_GET_CLASS (device)->is_up) return NM_DEVICE_GET_CLASS (device)->is_up (device); @@ -87,6 +88,7 @@ is_available (NMDevice *device) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { /* Connections are always available because the carrier state is determined @@ -171,6 +173,7 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMSettingTeam *s_team = nm_connection_get_setting_team (connection); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); @@ -178,8 +181,7 @@ update_connection (NMDevice *device, NMConnection *connection) } g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); - teamd_start (device, s_team); - if (NM_DEVICE_TEAM_GET_PRIVATE (device)->teamd_pid > 0 && ensure_teamd_connection (device)) { + if (priv->tdc) { const char *config = NULL; int err; @@ -261,49 +263,30 @@ master_update_slave_connection (NMDevice *self, /******************************************************************/ static void -teamd_timeout_remove (NMDevice *device) +teamd_cleanup (NMDevice *device, gboolean free_tdc) { NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); - if (priv->teamd_timeout) { - g_source_remove (priv->teamd_timeout); - priv->teamd_timeout = 0; - } -} - -static void -teamd_cleanup (NMDevice *device, gboolean device_state_failed) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); - - if (priv->teamd_dbus_watch) { - g_bus_unwatch_name (priv->teamd_dbus_watch); - priv->teamd_dbus_watch = 0; - } - if (priv->teamd_process_watch) { g_source_remove (priv->teamd_process_watch); priv->teamd_process_watch = 0; } + if (priv->teamd_timeout) { + g_source_remove (priv->teamd_timeout); + priv->teamd_timeout = 0; + } + if (priv->teamd_pid > 0) { nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, "teamd", 2000, NULL, NULL); priv->teamd_pid = 0; } - if (priv->tdc) { + if (priv->tdc && free_tdc) { teamdctl_disconnect (priv->tdc); teamdctl_free (priv->tdc); priv->tdc = NULL; } - - teamd_timeout_remove (device); - - if (device_state_failed) { - if (nm_device_is_activating (device) || - (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } } static gboolean @@ -314,11 +297,18 @@ teamd_timeout_cb (gpointer user_data) NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); g_return_val_if_fail (priv->teamd_timeout, FALSE); + priv->teamd_timeout = 0; - _LOGI (LOGD_TEAM, "teamd timed out."); - teamd_cleanup (device, TRUE); + if (priv->teamd_pid && !priv->tdc) { + /* Timed out launching our own teamd process */ + _LOGW (LOGD_TEAM, "teamd timed out."); + teamd_cleanup (device, TRUE); - return FALSE; + g_warn_if_fail (nm_device_is_activating (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } + + return G_SOURCE_REMOVE; } static void @@ -335,43 +325,77 @@ teamd_dbus_appeared (GDBusConnection *connection, g_return_if_fail (priv->teamd_dbus_watch); _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); - teamd_timeout_remove (device); + nm_device_queue_recheck_assume (device); + + /* If another teamd grabbed the bus name while our teamd was starting, + * just ignore the death of our teamd and run with the existing one. + */ + if (priv->teamd_process_watch) { + gs_unref_variant GVariant *ret = NULL; + guint32 pid; + + ret = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new ("(s)", name_owner), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 2000, + NULL, + NULL); + g_variant_get (ret, "(u)", &pid); + + if (pid != priv->teamd_pid) + teamd_cleanup (device, FALSE); + } + /* Grab a teamd control handle even if we aren't going to use it + * immediately. But if we are, and grabbing it failed, fail the + * device activation. + */ success = ensure_teamd_connection (device); if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) { if (success) nm_device_activate_schedule_stage2_device_config (device); else if (!nm_device_uses_assumed_connection (device)) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - return; } } static void -teamd_dbus_vanished (GDBusConnection *connection, +teamd_dbus_vanished (GDBusConnection *dbus_connection, const gchar *name, gpointer user_data) { NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); + NMDeviceState state = nm_device_get_state (device); g_return_if_fail (priv->teamd_dbus_watch); - if (priv->teamd_timeout) { + if (!priv->tdc) { /* g_bus_watch_name will always raise an initial signal, to indicate whether the - * name exists/not exists initially. Do not take this as a failure, until the - * startup timeout is over. - * - * Note that g_bus_watch_name is guaranteed to alternate vanished/appeared signals, - * so we won't hit this condition again (because the next signal is either 'appeared' - * or 'timeout'). */ - _LOGD (LOGD_TEAM, "teamd vanished from D-Bus (ignored)"); + * name exists/not exists initially. Do not take this as a failure if it hadn't + * previously appeared. + */ + _LOGD (LOGD_TEAM, "teamd not on D-Bus (ignored)"); return; } _LOGI (LOGD_TEAM, "teamd vanished from D-Bus"); teamd_cleanup (device, TRUE); + + /* Attempt to respawn teamd */ + if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) { + NMConnection *connection = nm_device_get_connection (device); + + g_assert (connection); + if (!teamd_start (device, nm_connection_get_setting_team (connection))) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } static void @@ -380,13 +404,24 @@ teamd_process_watch_cb (GPid pid, gint status, gpointer user_data) NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); + NMDeviceState state = nm_device_get_state (device); g_return_if_fail (priv->teamd_process_watch); - _LOGI (LOGD_TEAM, "teamd died with status %d", status); - priv->teamd_process_watch = 0; + _LOGD (LOGD_TEAM, "teamd died with status %d", status); priv->teamd_pid = 0; - teamd_cleanup (device, TRUE); + priv->teamd_process_watch = 0; + + /* If teamd quit within 5 seconds of starting, it's probably hosed + * and will just die again, so fail the activation. + */ + if (priv->teamd_timeout && + (state >= NM_DEVICE_STATE_PREPARE) && + (state <= NM_DEVICE_STATE_ACTIVATED)) { + _LOGW (LOGD_TEAM, "teamd process quit unexpectedly; failing activation"); + teamd_cleanup (device, TRUE); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } static void @@ -407,28 +442,41 @@ teamd_child_setup (gpointer user_data G_GNUC_UNUSED) } static gboolean +teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error) +{ + gs_unref_ptrarray GPtrArray *argv = NULL; + gs_free char *tmp_str = NULL; + + if (!teamd_binary) { + teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); + if (!teamd_binary) { + _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); + return FALSE; + } + } + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (gpointer) teamd_binary); + g_ptr_array_add (argv, (gpointer) "-k"); + g_ptr_array_add (argv, (gpointer) "-t"); + g_ptr_array_add (argv, (gpointer) nm_device_get_iface (NM_DEVICE (self))); + g_ptr_array_add (argv, NULL); + + _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + return g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, NULL, error); +} + +static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); const char *iface = nm_device_get_ip_iface (device); - char *tmp_str = NULL; - const char *config; + gs_unref_ptrarray GPtrArray *argv = NULL; + gs_free_error GError *error = NULL; + gs_free char *tmp_str = NULL; const char *teamd_binary; - GPtrArray *argv; - GError *error = NULL; - gboolean ret; - int status; - - if (priv->teamd_dbus_watch || - priv->teamd_process_watch || - priv->teamd_pid > 0 || - priv->tdc || - priv->teamd_timeout) - { - /* Just return if teamd_start() was already called */ - return TRUE; - } + const char *config; teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); if (!teamd_binary) { @@ -436,20 +484,12 @@ teamd_start (NMDevice *device, NMSettingTeam *s_team) return FALSE; } - /* Kill teamd for same named device first if it is there */ - argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) teamd_binary); - g_ptr_array_add (argv, (gpointer) "-k"); - g_ptr_array_add (argv, (gpointer) "-t"); - g_ptr_array_add (argv, (gpointer) iface); - g_ptr_array_add (argv, NULL); - - _LOGD (LOGD_TEAM, "running: %s", - (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); - g_clear_pointer (&tmp_str, g_free); - - ret = g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &error); - g_ptr_array_free (argv, TRUE); + if (priv->teamd_process_watch || priv->teamd_pid > 0 || priv->tdc) { + g_warn_if_reached (); + if (!priv->teamd_pid) + teamd_kill (self, teamd_binary, NULL); + teamd_cleanup (device, TRUE); + } /* Start teamd now */ argv = g_ptr_array_new (); @@ -472,83 +512,90 @@ teamd_start (NMDevice *device, NMSettingTeam *s_team) g_ptr_array_add (argv, (gpointer) "-gg"); g_ptr_array_add (argv, NULL); - _LOGD (LOGD_TEAM, "running: %s", - (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); - g_clear_pointer (&tmp_str, g_free); - - /* Start a timeout for teamd to appear at D-Bus */ - priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device); - - /* Register D-Bus name watcher */ - tmp_str = g_strdup_printf ("org.libteam.teamd.%s", iface); - priv->teamd_dbus_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - tmp_str, - G_BUS_NAME_WATCHER_FLAGS_NONE, - teamd_dbus_appeared, - teamd_dbus_vanished, - device, - NULL); - g_free (tmp_str); - - ret = g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, - &teamd_child_setup, NULL, &priv->teamd_pid, &error); - g_ptr_array_free (argv, TRUE); - if (!ret) { + _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + if (!g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, + teamd_child_setup, NULL, &priv->teamd_pid, &error)) { _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); - g_clear_error (&error); - teamd_cleanup (device, FALSE); + teamd_cleanup (device, TRUE); return FALSE; } + /* Start a timeout for teamd to appear at D-Bus */ + if (!priv->teamd_timeout) + priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device); + /* Monitor the child process so we know when it dies */ priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid, teamd_process_watch_cb, device); - _LOGI (LOGD_TEAM, "Activation: (team) started teamd..."); + _LOGI (LOGD_TEAM, "Activation: (team) started teamd [pid %u]...", (guint) priv->teamd_pid); return TRUE; } -static void -teamd_stop (NMDevice *device) -{ - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - - if (priv->teamd_pid > 0) - _LOGI (LOGD_TEAM, "Deactivation: stopping teamd..."); - else - _LOGD (LOGD_TEAM, "Deactivation: stopping teamd (not started)..."); - teamd_cleanup (device, FALSE); -} - static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + gs_free_error GError *error = NULL; NMConnection *connection; NMSettingTeam *s_team; + const char *cfg; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - connection = nm_device_get_connection (device); - g_assert (connection); - s_team = nm_connection_get_setting_team (connection); - g_assert (s_team); - if (teamd_start (device, s_team)) - ret = NM_ACT_STAGE_RETURN_POSTPONE; - else - ret = NM_ACT_STAGE_RETURN_FAILURE; + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) + return ret; + + connection = nm_device_get_connection (device); + g_assert (connection); + s_team = nm_connection_get_setting_team (connection); + g_assert (s_team); + + if (priv->tdc) { + /* If the existing teamd config is the same as we're about to use, + * then we can proceed. If it's not the same, and we have a PID, + * kill it so we can respawn it with the right config. If we don't + * have a PID, then we must fail. + */ + cfg = teamdctl_config_get_raw (priv->tdc); + if (cfg && strcmp (cfg, nm_setting_team_get_config (s_team)) == 0) { + _LOGD (LOGD_TEAM, "using existing matching teamd config"); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + if (!priv->teamd_pid) { + _LOGD (LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl"); + if (!teamd_kill (self, NULL, &error)) { + _LOGW (LOGD_TEAM, "existing teamd config mismatch; failed to kill existing teamd: %s", error->message); + *reason = NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + _LOGD (LOGD_TEAM, "existing teamd config mismatch; respawning..."); + teamd_cleanup (device, TRUE); } - return ret; + + return teamd_start (device, s_team) ? + NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; } static void deactivate (NMDevice *device) { - teamd_stop (device); + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + + if (priv->teamd_pid || priv->tdc) + _LOGI (LOGD_TEAM, "deactivation: stopping teamd..."); + + if (!priv->teamd_pid) + teamd_kill (self, NULL, NULL); + teamd_cleanup (device, TRUE); } static gboolean @@ -694,6 +741,27 @@ nm_device_team_init (NMDeviceTeam * self) } static void +constructed (GObject *object) +{ + NMDevice *device = NM_DEVICE (object); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + char *tmp_str = NULL; + + G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object); + + /* Register D-Bus name watcher */ + tmp_str = g_strdup_printf ("org.libteam.teamd.%s", nm_device_get_ip_iface (device)); + priv->teamd_dbus_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + tmp_str, + G_BUS_NAME_WATCHER_FLAGS_NONE, + teamd_dbus_appeared, + teamd_dbus_vanished, + NM_DEVICE (device), + NULL); + g_free (tmp_str); +} + +static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { @@ -730,7 +798,15 @@ set_property (GObject *object, guint prop_id, static void dispose (GObject *object) { - teamd_cleanup (NM_DEVICE (object), FALSE); + NMDevice *device = NM_DEVICE (object); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + if (priv->teamd_dbus_watch) { + g_bus_unwatch_name (priv->teamd_dbus_watch); + priv->teamd_dbus_watch = 0; + } + + teamd_cleanup (device, TRUE); G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); } @@ -746,6 +822,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->connection_type = NM_SETTING_TEAM_SETTING_NAME; /* virtual methods */ + object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; diff --git a/src/devices/wifi/Makefile.in b/src/devices/wifi/Makefile.in index 175dd900..f5e88007 100644 --- a/src/devices/wifi/Makefile.in +++ b/src/devices/wifi/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/devices/wifi -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -226,6 +235,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -277,7 +288,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -312,6 +322,7 @@ 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@ @@ -583,7 +594,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/wifi/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/wifi/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -658,14 +668,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -968,6 +978,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES tags tags-am uninstall uninstall-am \ uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 0f5aa164..dc3dfbc6 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -235,7 +235,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } static gboolean -is_available (NMDevice *device) +is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index dd7754b3..ce9a3f75 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -863,10 +863,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) static gboolean -_internal_check_connection_available (NMDevice *device, - NMConnection *connection, - const char *specific_object, - gboolean ignore_ap_list) +check_connection_available (NMDevice *device, + NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, + const char *specific_object) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); NMSettingWireless *s_wifi; @@ -876,6 +876,9 @@ _internal_check_connection_available (NMDevice *device, s_wifi = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wifi, FALSE); + /* a connection that is available for a certain @specific_object, MUST + * also be available in general (without @specific_object). */ + if (specific_object) { NMAccessPoint *ap; @@ -891,8 +894,15 @@ _internal_check_connection_available (NMDevice *device, || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) return TRUE; - /* Hidden SSIDs obviously don't always appear in the scan list either */ - if (nm_setting_wireless_get_hidden (s_wifi) || ignore_ap_list) + /* Hidden SSIDs obviously don't always appear in the scan list either. + * + * For an explict user-activation-request, a connection is considered + * available because for hidden Wi-Fi, clients didn't consistently + * set the 'hidden' property to indicate hidden SSID networks. If + * activating but the network isn't available let the device recheck + * availability. + */ + if (nm_setting_wireless_get_hidden (s_wifi) || NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) return TRUE; /* check if its visible */ @@ -904,24 +914,6 @@ _internal_check_connection_available (NMDevice *device, return FALSE; } -static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - const char *specific_object) -{ - return _internal_check_connection_available (device, connection, specific_object, FALSE); -} - -/* FIXME: remove this function when we require the 'hidden' property to be - * set before a hidden connection can be activated. - */ -static gboolean -check_connection_available_wifi_hidden (NMDevice *device, - NMConnection *connection) -{ - return _internal_check_connection_available (device, connection, NULL, TRUE); -} - /* * List of manufacturer default SSIDs that are often unchanged by users. * @@ -1143,28 +1135,22 @@ complete_connection (NMDevice *device, } static gboolean -is_available (NMDevice *device) +is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); guint32 state; - if (!priv->enabled) { - _LOGD (LOGD_WIFI, "not available because not enabled"); + if (!priv->enabled) return FALSE; - } - if (!priv->sup_iface) { - _LOGD (LOGD_WIFI, "not available because supplicant not running"); + if (!priv->sup_iface) return FALSE; - } state = nm_supplicant_interface_get_state (priv->sup_iface); if ( state < NM_SUPPLICANT_INTERFACE_STATE_READY - || state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) { - _LOGD (LOGD_WIFI, "not available because supplicant interface not ready"); + || state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) return FALSE; - } return TRUE; } @@ -1522,7 +1508,9 @@ request_wireless_scan (gpointer user_data) for (i = 0; i < ssids->len; i++) { ssid = g_ptr_array_index (ssids, i); - foo = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); + foo = ssid->len > 0 + ? nm_utils_ssid_to_utf8 (ssid->data, ssid->len) + : NULL; _LOGD (LOGD_WIFI_SCAN, "(%d) probe scanning SSID '%s'", i, foo ? foo : "<hidden>"); g_free (foo); @@ -1636,6 +1624,8 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, * */ +#define WPAS_REMOVED_TAG "supplicant-removed" + static void try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) { @@ -1743,6 +1733,7 @@ merge_scanned_ap (NMDeviceWifi *self, * fake, since it clearly exists somewhere. */ nm_ap_set_fake (found_ap, FALSE); + g_object_set_data (G_OBJECT (found_ap), WPAS_REMOVED_TAG, NULL); } else { /* New entry in the list */ _LOGD (LOGD_WIFI_SCAN, "adding new AP '%s' %s (%p)", @@ -1756,8 +1747,6 @@ merge_scanned_ap (NMDeviceWifi *self, } } -#define WPAS_REMOVED_TAG "supplicant-removed" - static gboolean cull_scan_list (NMDeviceWifi *self) { @@ -1912,9 +1901,23 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, g_return_if_fail (object_path != NULL); ap = get_ap_by_supplicant_path (self, object_path); - if (ap) + if (ap) { + gint32 now = nm_utils_get_monotonic_timestamp_s (); + gint32 last_seen = nm_ap_get_last_seen (ap); + + /* We don't know when the supplicant last saw the AP's beacons, + * it could be two minutes or it could be 2 seconds. Because the + * supplicant doesn't send property change notifications if the + * AP's other properties don't change, our last-seen time may be + * much older the supplicant's, and the AP would be immediately + * removed from the list on the next cleanup. So update the + * last-seen time to ensure the AP sticks around for at least + * one more periodic scan. + */ + nm_ap_set_last_seen (ap, MAX (last_seen, now - SCAN_INTERVAL_MAX)); g_object_set_data (G_OBJECT (ap), WPAS_REMOVED_TAG, GUINT_TO_POINTER (TRUE)); } +} static void remove_supplicant_timeouts (NMDeviceWifi *self) @@ -2169,7 +2172,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, /* If the interface can now be activated because the supplicant is now * available, transition to DISCONNECTED. */ - if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) { + if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE); @@ -3335,7 +3338,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->is_available = is_available; parent_class->check_connection_compatible = check_connection_compatible; parent_class->check_connection_available = check_connection_available; - parent_class->check_connection_available_wifi_hidden = check_connection_available_wifi_hidden; parent_class->complete_connection = complete_connection; parent_class->set_enabled = set_enabled; diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index ee07cf40..66d73563 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -808,7 +808,7 @@ nm_ap_set_ssid (NMAccessPoint *ap, const guint8 *ssid, gsize len) NM80211ApFlags nm_ap_get_flags (NMAccessPoint *ap) { - g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_SEC_NONE); + g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_FLAGS_NONE); return NM_AP_GET_PRIVATE (ap)->flags; } diff --git a/src/devices/wifi/tests/Makefile.am b/src/devices/wifi/tests/Makefile.am index 09c6401f..2a7d7849 100644 --- a/src/devices/wifi/tests/Makefile.am +++ b/src/devices/wifi/tests/Makefile.am @@ -23,5 +23,6 @@ test_wifi_ap_utils_SOURCES = \ test_wifi_ap_utils_LDADD = $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-wifi-ap-utils diff --git a/src/devices/wifi/tests/Makefile.in b/src/devices/wifi/tests/Makefile.in index a8ae2e9d..e3b7c767 100644 --- a/src/devices/wifi/tests/Makefile.in +++ b/src/devices/wifi/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ noinst_PROGRAMS = test-wifi-ap-utils$(EXEEXT) TESTS = test-wifi-ap-utils$(EXEEXT) subdir = src/devices/wifi/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -195,6 +204,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -221,7 +232,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -256,6 +266,7 @@ 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@ @@ -494,7 +505,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/wifi/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/wifi/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -541,14 +551,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -888,6 +898,10 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +@VALGRIND_RULES@ # 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/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c index fb335b89..3c405e26 100644 --- a/src/devices/wifi/tests/test-wifi-ap-utils.c +++ b/src/devices/wifi/tests/test-wifi-ap-utils.c @@ -785,6 +785,7 @@ test_priv_ap_leap_connection_1 (gconstpointer add_wifi) COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); + g_object_unref (expected); } /*******************************************/ @@ -866,6 +867,7 @@ test_priv_ap_dynamic_wep_1 (void) COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); + g_object_unref (expected); } /*******************************************/ @@ -913,6 +915,7 @@ test_priv_ap_dynamic_wep_2 (void) COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); + g_object_unref (expected); } /*******************************************/ diff --git a/src/devices/wimax/Makefile.in b/src/devices/wimax/Makefile.in index f1ffb09c..32800fb7 100644 --- a/src/devices/wimax/Makefile.in +++ b/src/devices/wimax/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/devices/wimax -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -205,6 +214,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -231,7 +242,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -266,6 +276,7 @@ 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@ @@ -526,7 +537,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/wimax/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/wimax/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -600,14 +610,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -835,6 +845,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml dbus-binding-tool --prefix=nm_wimax_nsp --mode=glib-server --output=$@ $< diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c index 466cd979..0c8f1cbb 100644 --- a/src/devices/wimax/nm-device-wimax.c +++ b/src/devices/wimax/nm-device-wimax.c @@ -239,7 +239,7 @@ update_availability (NMDeviceWimax *self, gboolean old_available) NMDeviceState state; gboolean new_available, changed = FALSE; - new_available = nm_device_is_available (device); + new_available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); if (new_available == old_available) return FALSE; @@ -281,7 +281,7 @@ set_enabled (NMDevice *device, gboolean enabled) if (priv->enabled == enabled) return; - old_available = nm_device_is_available (NM_DEVICE (device)); + old_available = nm_device_is_available (NM_DEVICE (device), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); priv->enabled = enabled; nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s", @@ -334,12 +334,16 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); const GSList *ns_iter = NULL; NMWimaxNsp *nsp; + /* a connection that is available for a certain @specific_object, MUST + * also be available in general (without @specific_object). */ + if (specific_object) { nsp = get_nsp_by_path (NM_DEVICE_WIMAX (device), specific_object); return nsp ? nm_wimax_nsp_check_compatible (nsp, connection) : FALSE; @@ -484,30 +488,21 @@ can_auto_connect (NMDevice *device, } static gboolean -is_available (NMDevice *device) +is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); - if (!priv->enabled) { - nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled", iface); + if (!priv->enabled) return FALSE; - } - if (!priv->wimaxd_enabled) { - nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled in wimaxd", iface); + if (!priv->wimaxd_enabled) return FALSE; - } - if (!nm_wimax_util_sdk_is_initialized ()) { - nm_log_dbg (LOGD_WIMAX, "(%s): not available because WiMAX SDK not initialized", iface); + if (!nm_wimax_util_sdk_is_initialized ()) return FALSE; - } - if (!priv->sdk) { - nm_log_dbg (LOGD_WIMAX, "(%s): not available because not known to WiMAX SDK", iface); + if (!priv->sdk) return FALSE; - } return iwmxsdk_status_get (priv->sdk) >= WIMAX_API_DEVICE_STATUS_Ready; } @@ -712,7 +707,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, return; state = nm_device_get_state (NM_DEVICE (self)); - old_available = nm_device_is_available (NM_DEVICE (self)); + old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); priv->status = new_status; if (priv->current_nsp) @@ -1153,7 +1148,7 @@ static gboolean sdk_action_defer_cb (gpointer user_data) { NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); - gboolean old_available = nm_device_is_available (NM_DEVICE (self)); + gboolean old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0; update_availability (self, old_available); diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index 18cbfdd3..1a8aef3b 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/devices/wwan -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -216,6 +225,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -242,7 +253,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -277,6 +287,7 @@ 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@ @@ -553,7 +564,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/wwan/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/devices/wwan/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -631,14 +641,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -866,6 +876,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index f681e59c..f819d1d7 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -295,16 +295,19 @@ modem_state_cb (NMModem *modem, * device's enabled/disabled state. */ nm_modem_set_mm_enabled (priv->modem, priv->rf_enabled); + + /* Now allow connections without a PIN to be available */ + nm_device_recheck_available_connections (device); } - if ((dev_state >= NM_DEVICE_STATE_DISCONNECTED) && !nm_device_is_available (device)) { + if ((dev_state >= NM_DEVICE_STATE_DISCONNECTED) && !nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_MODEM_FAILED); return; } - if ((dev_state == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) { + if ((dev_state == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_MODEM_AVAILABLE); @@ -391,6 +394,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) static gboolean check_connection_available (NMDevice *device, NMConnection *connection, + NMDeviceCheckConAvailableFlags flags, const char *specific_object) { NMDeviceModem *self = NM_DEVICE_MODEM (device); @@ -433,6 +437,50 @@ deactivate (NMDevice *device) nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device); } +/***********************************************************/ + +static gboolean +deactivate_async_finish (NMDevice *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +modem_deactivate_async_ready (NMModem *modem, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + if (!nm_modem_deactivate_async_finish (modem, res, &error)) + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +deactivate_async (NMDevice *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + deactivate_async); + nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE (self)->modem, + self, + cancellable, + (GAsyncReadyCallback) modem_deactivate_async_ready, + simple); +} + +/***********************************************************/ + static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { @@ -536,24 +584,19 @@ set_enabled (NMDevice *device, gboolean enabled) } static gboolean -is_available (NMDevice *device) +is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); NMModemState modem_state; - if (!priv->rf_enabled) { - _LOGD (LOGD_MB, "not available because WWAN airplane mode is on"); + if (!priv->rf_enabled) return FALSE; - } g_assert (priv->modem); modem_state = nm_modem_get_state (priv->modem); - if (modem_state <= NM_MODEM_STATE_INITIALIZING) { - _LOGD (LOGD_MB, "not available because modem is not ready (%s)", - nm_modem_state_to_string (modem_state)); + if (modem_state <= NM_MODEM_STATE_INITIALIZING) return FALSE; - } return TRUE; } @@ -638,7 +681,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); @@ -661,7 +704,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); @@ -711,6 +754,8 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->check_connection_compatible = check_connection_compatible; device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; + device_class->deactivate_async = deactivate_async; + device_class->deactivate_async_finish = deactivate_async_finish; device_class->deactivate = deactivate; device_class->act_stage1_prepare = act_stage1_prepare; device_class->act_stage2_config = act_stage2_config; diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index f8239b79..4bb72fd1 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -42,7 +42,7 @@ struct _NMModemBroadbandPrivate { MMModemSimple *simple_iface; /* Connection setup */ - MMSimpleConnectProperties *connect_properties; + MMBearer *bearer; MMBearerIpConfig *ipv4_config; MMBearerIpConfig *ipv6_config; @@ -176,78 +176,6 @@ get_bearer_ip_method (MMBearerIpConfig *config) return NM_MODEM_IP_METHOD_UNKNOWN; } -static void -connect_ready (MMModemSimple *simple_iface, - GAsyncResult *res, - NMModemBroadband *self) -{ - GError *error = NULL; - NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; - NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; - - g_clear_object (&self->priv->connect_properties); - - self->priv->bearer = mm_modem_simple_connect_finish (simple_iface, res, &error); - if (!self->priv->bearer) { - if (g_error_matches (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || - (g_error_matches (error, - MM_CORE_ERROR, - MM_CORE_ERROR_UNAUTHORIZED) && - mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { - /* Request PIN */ - ask_for_pin (self); - } else { - /* Strip remote error info before logging it */ - if (g_dbus_error_is_remote_error (error)) - g_dbus_error_strip_remote_error (error); - - nm_log_warn (LOGD_MB, "(%s) failed to connect modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - error && error->message ? error->message : "(unknown)"); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); - } - - g_clear_error (&error); - g_object_unref (self); - return; - } - - /* Grab IP configurations */ - self->priv->ipv4_config = mm_bearer_get_ipv4_config (self->priv->bearer); - if (self->priv->ipv4_config) - ip4_method = get_bearer_ip_method (self->priv->ipv4_config); - - self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); - if (self->priv->ipv6_config) - ip6_method = get_bearer_ip_method (self->priv->ipv6_config); - - if (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN && - ip6_method == NM_MODEM_IP_METHOD_UNKNOWN) { - nm_log_warn (LOGD_MB, "(%s) failed to connect modem: invalid bearer IP configuration", - nm_modem_get_uid (NM_MODEM (self))); - - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "invalid bearer IP configuration"); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, error); - g_error_free (error); - g_object_unref (self); - return; - } - - g_object_set (self, - NM_MODEM_DATA_PORT, mm_bearer_get_interface (self->priv->bearer), - NM_MODEM_IP4_METHOD, ip4_method, - NM_MODEM_IP6_METHOD, ip6_method, - NM_MODEM_IP_TIMEOUT, mm_bearer_get_ip_timeout (self->priv->bearer), - NULL); - - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); - g_object_unref (self); -} - static MMSimpleConnectProperties * create_cdma_connect_properties (NMConnection *connection) { @@ -266,15 +194,12 @@ create_cdma_connect_properties (NMConnection *connection) } static MMSimpleConnectProperties * -create_gsm_connect_properties (NMModem *modem, - NMConnection *connection, - GError **error) +create_gsm_connect_properties (NMConnection *connection) { NMSettingGsm *setting; NMSettingPpp *s_ppp; MMSimpleConnectProperties *properties; const gchar *str; - NMModemIPType ip_type; setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); @@ -329,23 +254,137 @@ create_gsm_connect_properties (NMModem *modem, mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); } - /* Determine IP types to use when connecting */ - ip_type = nm_modem_get_connection_ip_type (modem, connection, error); - if (ip_type == NM_MODEM_IP_TYPE_UNKNOWN) { - g_object_unref (properties); - return NULL; + return properties; +} + +typedef struct { + NMModemBroadband *self; + MMModemCapability caps; + MMSimpleConnectProperties *connect_properties; + GArray *ip_types; + guint ip_types_i; + GError *first_error; +} ActStageContext; + +static void +act_stage_context_free (ActStageContext *ctx) +{ + g_clear_error (&ctx->first_error); + g_clear_pointer (&ctx->ip_types, (GDestroyNotify) g_array_unref); + g_clear_object (&ctx->connect_properties); + g_object_unref (ctx->self); + g_slice_free (ActStageContext, ctx); +} + +static void act_stage_context_step (ActStageContext *ctx); + +static void +connect_ready (MMModemSimple *simple_iface, + GAsyncResult *res, + ActStageContext *ctx) +{ + GError *error = NULL; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; + + ctx->self->priv->bearer = mm_modem_simple_connect_finish (simple_iface, res, &error); + if (!ctx->self->priv->bearer) { + if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || + (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) && + mm_modem_get_unlock_required (ctx->self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { + /* Request PIN */ + ask_for_pin (ctx->self); + g_error_free (error); + act_stage_context_free (ctx); + return; + } + + /* Save the error, if it's the first one */ + if (!ctx->first_error) { + /* Strip remote error info before saving it */ + if (g_dbus_error_is_remote_error (error)) + g_dbus_error_strip_remote_error (error); + ctx->first_error = error; + } else + g_error_free (error); + + /* If the modem/provider lies and the IP type we tried isn't supported, + * retry with the next one, if any. + */ + ctx->ip_types_i++; + act_stage_context_step (ctx); + return; } - if (ip_type == NM_MODEM_IP_TYPE_IPV4) - mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4); - else if (ip_type == NM_MODEM_IP_TYPE_IPV6) - mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV6); - else if (ip_type == NM_MODEM_IP_TYPE_IPV4V6) - mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4V6); - else - g_assert_not_reached (); + /* Grab IP configurations */ + ctx->self->priv->ipv4_config = mm_bearer_get_ipv4_config (ctx->self->priv->bearer); + if (ctx->self->priv->ipv4_config) + ip4_method = get_bearer_ip_method (ctx->self->priv->ipv4_config); - return properties; + ctx->self->priv->ipv6_config = mm_bearer_get_ipv6_config (ctx->self->priv->bearer); + if (ctx->self->priv->ipv6_config) + ip6_method = get_bearer_ip_method (ctx->self->priv->ipv6_config); + + if (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN && + ip6_method == NM_MODEM_IP_METHOD_UNKNOWN) { + nm_log_warn (LOGD_MB, "(%s): failed to connect modem: invalid bearer IP configuration", + nm_modem_get_uid (NM_MODEM (ctx->self))); + g_signal_emit_by_name (ctx->self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + act_stage_context_free (ctx); + return; + } + + g_object_set (ctx->self, + NM_MODEM_DATA_PORT, mm_bearer_get_interface (ctx->self->priv->bearer), + NM_MODEM_IP4_METHOD, ip4_method, + NM_MODEM_IP6_METHOD, ip6_method, + NM_MODEM_IP_TIMEOUT, mm_bearer_get_ip_timeout (ctx->self->priv->bearer), + NULL); + + g_signal_emit_by_name (ctx->self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); + act_stage_context_free (ctx); +} + +static void +act_stage_context_step (ActStageContext *ctx) +{ + if (ctx->ip_types_i < ctx->ip_types->len) { + NMModemIPType current; + + current = g_array_index (ctx->ip_types, NMModemIPType, ctx->ip_types_i); + + if (current == NM_MODEM_IP_TYPE_IPV4) + mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV4); + else if (current == NM_MODEM_IP_TYPE_IPV6) + mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV6); + else if (current == NM_MODEM_IP_TYPE_IPV4V6) + mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV4V6); + else + g_assert_not_reached (); + + nm_log_dbg (LOGD_MB, "(%s): launching connection with ip type '%s'", + nm_modem_get_uid (NM_MODEM (ctx->self)), + nm_modem_ip_type_to_string (current)); + + mm_modem_simple_connect (ctx->self->priv->simple_iface, + ctx->connect_properties, + NULL, + (GAsyncReadyCallback)connect_ready, + ctx); + return; + } + + /* If we have a saved error from a previous attempt, use it */ + if (!ctx->first_error) + ctx->first_error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "invalid bearer IP configuration"); + + nm_log_warn (LOGD_MB, "(%s): failed to connect modem: %s", + nm_modem_get_uid (NM_MODEM (ctx->self)), + ctx->first_error->message); + g_signal_emit_by_name (ctx->self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (ctx->first_error)); + act_stage_context_free (ctx); } static NMActStageReturn @@ -354,42 +393,55 @@ act_stage1_prepare (NMModem *_self, NMDeviceStateReason *reason) { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - MMModemCapability caps; + ActStageContext *ctx; GError *error = NULL; - g_clear_object (&self->priv->connect_properties); + /* Make sure we can get the Simple interface from the modem */ + if (!self->priv->simple_iface) { + self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object); + if (!self->priv->simple_iface) { + nm_log_warn (LOGD_MB, "(%s) cannot access the Simple mobile broadband modem interface", + nm_modem_get_uid (NM_MODEM (self))); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + /* Allocate new context for this activation stage attempt */ + ctx = g_slice_new0 (ActStageContext); + ctx->self = NM_MODEM_BROADBAND (g_object_ref (self)); + ctx->caps = mm_modem_get_current_capabilities (self->priv->modem_iface); - caps = mm_modem_get_current_capabilities (self->priv->modem_iface); - if (MODEM_CAPS_3GPP (caps)) - self->priv->connect_properties = create_gsm_connect_properties (_self, connection, &error); - else if (MODEM_CAPS_3GPP2 (caps)) - self->priv->connect_properties = create_cdma_connect_properties (connection); + /* Create core connect properties based on the modem capabilities */ + if (MODEM_CAPS_3GPP (ctx->caps)) + ctx->connect_properties = create_gsm_connect_properties (connection); + else if (MODEM_CAPS_3GPP2 (ctx->caps)) + ctx->connect_properties = create_cdma_connect_properties (connection); else { - nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem", - nm_modem_get_uid (NM_MODEM (self))); + nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': not a mobile broadband modem", + nm_modem_get_uid (NM_MODEM (self)), + nm_connection_get_id (connection)); + act_stage_context_free (ctx); *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } + g_assert (ctx->connect_properties); - if (error) { + /* Checkout list of IP types that we need to use in the retries */ + ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), connection, &error); + if (!ctx->ip_types) { nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s", nm_modem_get_uid (NM_MODEM (self)), nm_connection_get_id (connection), - error->message); + error ? error->message : "unknown error"); g_clear_error (&error); + act_stage_context_free (ctx); *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } - if (!self->priv->simple_iface) - self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object); - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->priv->simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000); - mm_modem_simple_connect (self->priv->simple_iface, - self->priv->connect_properties, - NULL, - (GAsyncReadyCallback)connect_ready, - g_object_ref (self)); + act_stage_context_step (ctx); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -566,9 +618,9 @@ set_power_state_low_ready (MMModem *modem, if (!mm_modem_set_power_state_finish (modem, result, &error)) { /* Log but ignore errors; not all modems support low power state */ - nm_log_dbg (LOGD_MB, "(%s) failed to set modem low power state: %s", - nm_modem_get_uid (NM_MODEM (self)), - error && error->message ? error->message : "(unknown)"); + nm_log_dbg (LOGD_MB, "(%s): failed to set modem low power state: %s", + nm_modem_get_uid (NM_MODEM (self)), + error && error->message ? error->message : "(unknown)"); g_clear_error (&error); } @@ -591,7 +643,7 @@ modem_disable_ready (MMModem *modem_iface, (GAsyncReadyCallback) set_power_state_low_ready, g_object_ref (self)); } else { - nm_log_warn (LOGD_MB, "(%s) failed to disable modem: %s", + nm_log_warn (LOGD_MB, "(%s): failed to disable modem: %s", nm_modem_get_uid (NM_MODEM (self)), error && error->message ? error->message : "(unknown)"); nm_modem_set_prev_state (NM_MODEM (self), "disable failed"); @@ -708,7 +760,7 @@ static_stage3_ip4_done (NMModemBroadband *self) /* DNS servers */ dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config); - for (i = 0; dns[i]; i++) { + for (i = 0; dns && dns[i]; i++) { if ( ip4_string_to_num (dns[i], &address_network) && address_network > 0) { nm_ip4_config_add_nameserver (config, address_network); @@ -761,9 +813,9 @@ stage3_ip6_done (NMModemBroadband *self) /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ if (ip_method != NM_MODEM_IP_METHOD_AUTO) { error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: no address given", - nm_modem_get_uid (NM_MODEM (self))); + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: no address given", + nm_modem_get_uid (NM_MODEM (self))); } goto out; } @@ -792,10 +844,10 @@ stage3_ip6_done (NMModemBroadband *self) if (address_string) { if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", - nm_modem_get_uid (NM_MODEM (self)), - address_string); + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); goto out; } nm_log_info (LOGD_MB, " gateway %s", address_string); @@ -844,20 +896,47 @@ stage3_ip6_config_request (NMModem *_self, NMDeviceStateReason *reason) typedef struct { NMModemBroadband *self; + GSimpleAsyncResult *result; + GCancellable *cancellable; gboolean warn; -} SimpleDisconnectContext; +} DisconnectContext; static void -simple_disconnect_context_free (SimpleDisconnectContext *ctx) +disconnect_context_complete (DisconnectContext *ctx) { + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_object_unref (ctx->result); g_object_unref (ctx->self); - g_slice_free (SimpleDisconnectContext, ctx); + g_slice_free (DisconnectContext, ctx); +} + +static gboolean +disconnect_context_complete_if_cancelled (DisconnectContext *ctx) +{ + GError *error = NULL; + + if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + disconnect_context_complete (ctx); + return TRUE; + } + return FALSE; +} + +static gboolean +disconnect_finish (NMModem *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } static void simple_disconnect_ready (MMModemSimple *modem_iface, GAsyncResult *res, - SimpleDisconnectContext *ctx) + DisconnectContext *ctx) { GError *error = NULL; @@ -865,33 +944,48 @@ simple_disconnect_ready (MMModemSimple *modem_iface, if (ctx->warn) nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s", nm_modem_get_uid (NM_MODEM (ctx->self)), - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); + error->message); + g_simple_async_result_take_error (ctx->result, error); } - simple_disconnect_context_free (ctx); + disconnect_context_complete (ctx); } static void -disconnect (NMModem *modem, - gboolean warn) +disconnect (NMModem *self, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - SimpleDisconnectContext *ctx; - - if (!self->priv->simple_iface) - return; + DisconnectContext *ctx; - ctx = g_slice_new (SimpleDisconnectContext); + ctx = g_slice_new (DisconnectContext); ctx->self = g_object_ref (self); - + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + disconnect); /* Don't bother warning on FAILED since the modem is already gone */ ctx->warn = warn; + /* Setup cancellable */ + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + if (disconnect_context_complete_if_cancelled (ctx)) + return; + + /* If no simple iface, we're done */ + if (!ctx->self->priv->simple_iface) { + disconnect_context_complete (ctx); + return; + } + + nm_log_dbg (LOGD_MB, "(%s): notifying ModemManager about the modem disconnection", + nm_modem_get_uid (NM_MODEM (ctx->self))); mm_modem_simple_disconnect ( ctx->self->priv->simple_iface, NULL, /* bearer path; if NULL given ALL get disconnected */ - NULL, /* cancellable */ + cancellable, (GAsyncReadyCallback)simple_disconnect_ready, ctx); } @@ -899,7 +993,7 @@ disconnect (NMModem *modem, /*****************************************************************************/ static void -deactivate (NMModem *_self, NMDevice *device) +deactivate_cleanup (NMModem *_self, NMDevice *device) { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); @@ -913,7 +1007,7 @@ deactivate (NMModem *_self, NMDevice *device) self->priv->pin_tries = 0; /* Chain up parent's */ - NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate (_self, device); + NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (_self, device); } /*****************************************************************************/ @@ -1027,7 +1121,7 @@ get_sim_ready (MMModem *modem, NULL); g_object_unref (new_sim); } else { - nm_log_warn (LOGD_MB, "(%s) failed to retrieve SIM object: %s", + nm_log_warn (LOGD_MB, "(%s): failed to retrieve SIM object: %s", nm_modem_get_uid (NM_MODEM (self)), error && error->message ? error->message : "(unknown)"); } @@ -1062,7 +1156,7 @@ nm_modem_broadband_init (NMModemBroadband *self) static void set_property (GObject *object, guint prop_id, - const GValue *value, + const GValue *value, GParamSpec *pspec) { NMModemBroadband *self = NM_MODEM_BROADBAND (object); @@ -1095,7 +1189,7 @@ set_property (GObject *object, static void get_property (GObject *object, guint prop_id, - GValue *value, + GValue *value, GParamSpec *pspec) { NMModemBroadband *self = NM_MODEM_BROADBAND (object); @@ -1142,7 +1236,8 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; - modem_class->deactivate = deactivate; + modem_class->disconnect_finish = disconnect_finish; + modem_class->deactivate_cleanup = deactivate_cleanup; modem_class->set_mm_enabled = set_mm_enabled; modem_class->get_user_pass = get_user_pass; modem_class->check_connection_compatible = check_connection_compatible; diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index ba1db8a4..69eaddf3 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -175,23 +175,23 @@ nm_modem_set_mm_enabled (NMModem *self, NMModemState prev_state = priv->state; if (enabled && priv->state >= NM_MODEM_STATE_ENABLING) { - nm_log_dbg (LOGD_MB, "(%s) cannot enable modem: already enabled", + nm_log_dbg (LOGD_MB, "(%s): cannot enable modem: already enabled", nm_modem_get_uid (self)); return; } if (!enabled && priv->state <= NM_MODEM_STATE_DISABLING) { - nm_log_dbg (LOGD_MB, "(%s) cannot disable modem: already disabled", + nm_log_dbg (LOGD_MB, "(%s): cannot disable modem: already disabled", nm_modem_get_uid (self)); return; } if (priv->state <= NM_MODEM_STATE_INITIALIZING) { - nm_log_dbg (LOGD_MB, "(%s) cannot enable/disable modem: initializing or failed", + nm_log_dbg (LOGD_MB, "(%s): cannot enable/disable modem: initializing or failed", nm_modem_get_uid (self)); return; } else if (priv->state == NM_MODEM_STATE_LOCKED) { /* Don't try to enable if the modem is locked since that will fail */ - nm_log_warn (LOGD_MB, "(%s) cannot enable/disable modem: locked", + nm_log_warn (LOGD_MB, "(%s): cannot enable/disable modem: locked", nm_modem_get_uid (self)); /* Try to unlock the modem if it's being enabled */ @@ -221,17 +221,39 @@ nm_modem_get_supported_ip_types (NMModem *self) return NM_MODEM_GET_PRIVATE (self)->ip_types; } +const gchar * +nm_modem_ip_type_to_string (NMModemIPType ip_type) +{ + switch (ip_type) { + case NM_MODEM_IP_TYPE_IPV4: + return "ipv4"; + case NM_MODEM_IP_TYPE_IPV6: + return "ipv6"; + case NM_MODEM_IP_TYPE_IPV4V6: + return "ipv4v6"; + default: + g_return_val_if_reached ("unknown"); + } +} + +static GArray * +build_single_ip_type_array (NMModemIPType type) +{ + return g_array_append_val (g_array_sized_new (FALSE, FALSE, sizeof (NMModemIPType), 1), type); +} + /** * nm_modem_get_connection_ip_type: * @self: the #NMModem * @connection: the #NMConnection to determine IP type to use * - * Given a modem and a connection, determine which NMModemIpType to use + * Given a modem and a connection, determine which #NMModemIPTypes to use * when connecting. * - * Returns: a single %NMModemIpType value + * Returns: an array of #NMModemIpType values, in the order in which they + * should be tried. */ -NMModemIPType +GArray * nm_modem_get_connection_ip_type (NMModem *self, NMConnection *connection, GError **error) @@ -265,9 +287,9 @@ nm_modem_get_connection_ip_type (NMModem *self, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Connection requested IPv4 but IPv4 is " "unsuported by the modem."); - return NM_MODEM_IP_TYPE_UNKNOWN; + return NULL; } - return NM_MODEM_IP_TYPE_IPV4; + return build_single_ip_type_array (NM_MODEM_IP_TYPE_IPV4); } if (ip6 && !ip4) { @@ -277,38 +299,54 @@ nm_modem_get_connection_ip_type (NMModem *self, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Connection requested IPv6 but IPv6 is " "unsuported by the modem."); - return NM_MODEM_IP_TYPE_UNKNOWN; + return NULL; } - return NM_MODEM_IP_TYPE_IPV6; + return build_single_ip_type_array (NM_MODEM_IP_TYPE_IPV6); } if (ip4 && ip6) { - /* Modem supports dual-stack */ - if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) - return NM_MODEM_IP_TYPE_IPV4V6; + NMModemIPType type; + GArray *out; - /* Both IPv4 and IPv6 requested, but modem doesn't support dual-stack; - * if one method is marked "may-fail" then use the other. - */ - if (ip6_may_fail) - return NM_MODEM_IP_TYPE_IPV4; - else if (ip4_may_fail) - return NM_MODEM_IP_TYPE_IPV6; + out = g_array_sized_new (FALSE, FALSE, sizeof (NMModemIPType), 3); + /* Modem supports dual-stack? */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) { + type = NM_MODEM_IP_TYPE_IPV4V6; + g_array_append_val (out, type); + } + + /* If IPv6 may-fail=false, we should NOT try IPv4 as fallback */ + if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV4) && ip6_may_fail) { + type = NM_MODEM_IP_TYPE_IPV4; + g_array_append_val (out, type); + } + + /* If IPv4 may-fail=false, we should NOT try IPv6 as fallback */ + if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV6) && ip4_may_fail) { + type = NM_MODEM_IP_TYPE_IPV6; + g_array_append_val (out, type); + } + + if (out->len > 0) + return out; + + /* Error... */ + g_array_unref (out); g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Connection requested both IPv4 and IPv6 " "but dual-stack addressing is unsupported " "by the modem."); - return NM_MODEM_IP_TYPE_UNKNOWN; + return NULL; } g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Connection specified no IP configuration!"); - return NM_MODEM_IP_TYPE_UNKNOWN; + return NULL; } /*****************************************************************************/ @@ -343,9 +381,9 @@ set_data_port (NMModem *self, const char *new_data_port) static void ppp_ip4_config (NMPPPManager *ppp_manager, - const char *iface, - NMIP4Config *config, - gpointer user_data) + const char *iface, + NMIP4Config *config, + gpointer user_data) { NMModem *self = NM_MODEM (user_data); guint32 i, num; @@ -416,9 +454,9 @@ ppp_ip6_config (NMPPPManager *ppp_manager, static void ppp_stats (NMPPPManager *ppp_manager, - guint32 in_bytes, - guint32 out_bytes, - gpointer user_data) + guint32 in_bytes, + guint32 out_bytes, + gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); @@ -464,7 +502,8 @@ ppp_stage3_ip_config_start (NMModem *self, /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { - nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", + nm_log_info (LOGD_PPP, "(%s): using modem-specified IP timeout: %u seconds", + nm_modem_get_uid (self), priv->mm_ip_timeout); ip_timeout = priv->mm_ip_timeout; } @@ -486,7 +525,8 @@ ppp_stage3_ip_config_start (NMModem *self, ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { - nm_log_err (LOGD_PPP, "error starting PPP: (%d) %s", + nm_log_err (LOGD_PPP, "(%s): error starting PPP: (%d) %s", + nm_modem_get_uid (self), error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_error_free (error); @@ -705,7 +745,7 @@ modem_secrets_cb (NMActRequest *req, priv->secrets_id = 0; if (error) - nm_log_warn (LOGD_MB, "%s", error->message); + nm_log_warn (LOGD_MB, "(%s): %s", nm_modem_get_uid (self), error->message); g_signal_emit (self, signals[AUTH_RESULT], 0, error); } @@ -839,13 +879,12 @@ nm_modem_complete_connection (NMModem *self, /*****************************************************************************/ static void -deactivate (NMModem *self, NMDevice *device) +deactivate_cleanup (NMModem *self, NMDevice *device) { NMModemPrivate *priv; int ifindex; g_return_if_fail (NM_IS_MODEM (self)); - g_return_if_fail (NM_IS_DEVICE (device)); priv = NM_MODEM_GET_PRIVATE (self); @@ -864,15 +903,19 @@ deactivate (NMModem *self, NMDevice *device) priv->ppp_manager = NULL; } - if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || - priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || - priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || - priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { - ifindex = nm_device_get_ip_ifindex (device); - if (ifindex > 0) { - nm_platform_route_flush (ifindex); - nm_platform_address_flush (ifindex); - nm_platform_link_set_down (ifindex); + if (device) { + g_return_if_fail (NM_IS_DEVICE (device)); + + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || + priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { + ifindex = nm_device_get_ip_ifindex (device); + if (ifindex > 0) { + nm_platform_route_flush (ifindex); + nm_platform_address_flush (ifindex); + nm_platform_link_set_down (ifindex); + } } } priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; @@ -884,10 +927,176 @@ deactivate (NMModem *self, NMDevice *device) /*****************************************************************************/ +typedef enum { + DEACTIVATE_CONTEXT_STEP_FIRST, + DEACTIVATE_CONTEXT_STEP_CLEANUP, + DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP, + DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT, + DEACTIVATE_CONTEXT_STEP_LAST +} DeactivateContextStep; + +typedef struct { + NMModem *self; + NMDevice *device; + GCancellable *cancellable; + GSimpleAsyncResult *result; + DeactivateContextStep step; + NMPPPManager *ppp_manager; +} DeactivateContext; + +static void +deactivate_context_complete (DeactivateContext *ctx) +{ + if (ctx->ppp_manager) + g_object_unref (ctx->ppp_manager); + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->device); + g_object_unref (ctx->self); + g_slice_free (DeactivateContext, ctx); +} + +gboolean +nm_modem_deactivate_async_finish (NMModem *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void deactivate_step (DeactivateContext *ctx); + +static void +disconnect_ready (NMModem *self, + GAsyncResult *res, + DeactivateContext *ctx) +{ + GError *error = NULL; + + if (!NM_MODEM_GET_CLASS (self)->disconnect_finish (self, res, &error)) { + g_simple_async_result_take_error (ctx->result, error); + deactivate_context_complete (ctx); + return; + } + + /* Go on */ + ctx->step++; + deactivate_step (ctx); +} + +static void +ppp_manager_stop_ready (NMPPPManager *ppp_manager, + GAsyncResult *res, + DeactivateContext *ctx) +{ + GError *error = NULL; + + if (!nm_ppp_manager_stop_finish (ppp_manager, res, &error)) { + nm_log_warn (LOGD_MB, "(%s): cannot stop PPP manager: %s", + nm_modem_get_uid (ctx->self), + error->message); + g_simple_async_result_take_error (ctx->result, error); + deactivate_context_complete (ctx); + return; + } + + /* Go on */ + ctx->step++; + deactivate_step (ctx); +} + +static void +deactivate_step (DeactivateContext *ctx) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (ctx->self); + GError *error = NULL; + + /* Check cancellable in each step */ + if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + deactivate_context_complete (ctx); + return; + } + + switch (ctx->step) { + case DEACTIVATE_CONTEXT_STEP_FIRST: + ctx->step++; + /* Fall down */ + + case DEACTIVATE_CONTEXT_STEP_CLEANUP: + /* Make sure we keep a ref to the PPP manager if there is one */ + if (priv->ppp_manager) + ctx->ppp_manager = g_object_ref (priv->ppp_manager); + /* Run cleanup */ + NM_MODEM_GET_CLASS (ctx->self)->deactivate_cleanup (ctx->self, ctx->device); + ctx->step++; + /* Fall down */ + + case DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP: + /* If we have a PPP manager, stop it */ + if (ctx->ppp_manager) { + nm_ppp_manager_stop (ctx->ppp_manager, + ctx->cancellable, + (GAsyncReadyCallback) ppp_manager_stop_ready, + ctx); + return; + } + ctx->step++; + /* Fall down */ + + case DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT: + /* Disconnect asynchronously */ + NM_MODEM_GET_CLASS (ctx->self)->disconnect (ctx->self, + FALSE, + ctx->cancellable, + (GAsyncReadyCallback) disconnect_ready, + ctx); + return; + + case DEACTIVATE_CONTEXT_STEP_LAST: + nm_log_dbg (LOGD_MB, "(%s): modem deactivation finished", + nm_modem_get_uid (ctx->self)); + deactivate_context_complete (ctx); + return; + } + + g_assert_not_reached (); +} + +void +nm_modem_deactivate_async (NMModem *self, + NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + DeactivateContext *ctx; + + ctx = g_slice_new0 (DeactivateContext); + ctx->self = g_object_ref (self); + ctx->device = g_object_ref (device); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + nm_modem_deactivate_async); + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + /* Start */ + ctx->step = DEACTIVATE_CONTEXT_STEP_FIRST; + deactivate_step (ctx); +} + +/*****************************************************************************/ + void nm_modem_deactivate (NMModem *self, NMDevice *device) { - NM_MODEM_GET_CLASS (self)->deactivate (self, device); + /* First cleanup */ + NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device); + /* Then disconnect without waiting */ + NM_MODEM_GET_CLASS (self)->disconnect (self, FALSE, NULL, NULL, NULL); } /*****************************************************************************/ @@ -912,7 +1121,6 @@ nm_modem_device_state_changed (NMModem *self, switch (new_state) { case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: - case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_FAILED: if (priv->act_request) { cancel_get_secrets (self); @@ -924,7 +1132,9 @@ nm_modem_device_state_changed (NMModem *self, /* Don't bother warning on FAILED since the modem is already gone */ if (new_state == NM_DEVICE_STATE_FAILED) warn = FALSE; - NM_MODEM_GET_CLASS (self)->disconnect (self, warn); + /* First cleanup */ + NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL); + NM_MODEM_GET_CLASS (self)->disconnect (self, warn, NULL, NULL, NULL); } break; default: @@ -1030,8 +1240,8 @@ nm_modem_init (NMModem *self) static GObject* constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) + guint n_construct_params, + GObjectConstructParam *construct_params) { GObject *object; NMModemPrivate *priv; @@ -1056,7 +1266,7 @@ constructor (GType type, return object; - err: +err: g_object_unref (object); return NULL; } @@ -1209,7 +1419,7 @@ nm_modem_class_init (NMModemClass *klass) klass->act_stage1_prepare = act_stage1_prepare; klass->stage3_ip6_config_request = stage3_ip6_config_request; - klass->deactivate = deactivate; + klass->deactivate_cleanup = deactivate_cleanup; /* Properties */ diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index 2a4d9173..2cace890 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -143,9 +143,16 @@ typedef struct { void (*set_mm_enabled) (NMModem *self, gboolean enabled); - void (*disconnect) (NMModem *self, gboolean warn); + void (*disconnect) (NMModem *self, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*disconnect_finish) (NMModem *self, + GAsyncResult *res, + GError **error); - void (*deactivate) (NMModem *self, NMDevice *device); + void (*deactivate_cleanup) (NMModem *self, NMDevice *device); gboolean (*owns_port) (NMModem *self, const char *iface); @@ -218,6 +225,15 @@ gboolean nm_modem_get_secrets (NMModem *modem, void nm_modem_deactivate (NMModem *modem, NMDevice *device); +void nm_modem_deactivate_async (NMModem *self, + NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_modem_deactivate_async_finish (NMModem *self, + GAsyncResult *res, + GError **error); + void nm_modem_device_state_changed (NMModem *modem, NMDeviceState new_state, NMDeviceState old_state, @@ -237,7 +253,7 @@ NMModemIPType nm_modem_get_supported_ip_types (NMModem *self); /* For the modem-manager only */ void nm_modem_emit_removed (NMModem *self); -NMModemIPType nm_modem_get_connection_ip_type (NMModem *self, +GArray *nm_modem_get_connection_ip_type (NMModem *self, NMConnection *connection, GError **error); @@ -246,6 +262,8 @@ void nm_modem_emit_ip6_config_result (NMModem *self, NMIP6Config *config, GError *error); +const gchar *nm_modem_ip_type_to_string (NMModemIPType ip_type); + G_END_DECLS #endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/wwan-exports.ver b/src/devices/wwan/wwan-exports.ver index c23ab24b..23412de6 100644 --- a/src/devices/wwan/wwan-exports.ver +++ b/src/devices/wwan/wwan-exports.ver @@ -5,6 +5,8 @@ global: nm_modem_check_connection_compatible; nm_modem_complete_connection; nm_modem_deactivate; + nm_modem_deactivate_async; + nm_modem_deactivate_async_finish; nm_modem_device_state_changed; nm_modem_get_capabilities; nm_modem_get_control_port; diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in index 4dea1085..a609e8c6 100644 --- a/src/dhcp-manager/Makefile.in +++ b/src/dhcp-manager/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,7 +16,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ build_triplet = @build@ host_triplet = @host@ libexec_PROGRAMS = nm-dhcp-helper$(EXEEXT) subdir = src/dhcp-manager -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -202,6 +211,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -228,7 +239,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -263,6 +273,7 @@ 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@ @@ -493,7 +504,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/dhcp-manager/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/dhcp-manager/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -578,14 +588,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -843,6 +853,8 @@ uninstall-am: uninstall-dbusserviceDATA uninstall-libexecPROGRAMS tags tags-am uninstall uninstall-am uninstall-dbusserviceDATA \ uninstall-libexecPROGRAMS +.PRECIOUS: Makefile + # 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/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 47fa5317..a39ffcca 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -767,7 +767,13 @@ nm_dhcp_client_handle_event (gpointer unused, str_options, priv->priority); } - g_warn_if_fail (ip_config != NULL); + + /* Fail if no valid IP config was received */ + if (ip_config == NULL) { + nm_log_warn (LOGD_DHCP, "(%s): DHCP client bound but IP config not received", iface); + new_state = NM_DHCP_STATE_FAIL; + g_clear_pointer (&str_options, g_hash_table_unref); + } } } @@ -878,6 +884,8 @@ dispose (GObject *object) timeout_cleanup (self); g_clear_pointer (&priv->iface, g_free); + g_clear_pointer (&priv->hostname, g_free); + g_clear_pointer (&priv->uuid, g_free); if (priv->hwaddr) { g_byte_array_free (priv->hwaddr, TRUE); diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index 46e8e0b8..d1fe0c30 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -39,8 +39,8 @@ #define HOSTNAME4_TAG "send host-name" #define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager" -#define HOSTNAME6_TAG "send fqdn.fqdn" -#define HOSTNAME6_FORMAT HOSTNAME6_TAG " \"%s\"; # added by NetworkManager" +#define FQDN_TAG "send fqdn.fqdn" +#define FQDN_FORMAT FQDN_TAG " \"%s\"; # added by NetworkManager" #define ALSOREQ_TAG "also request " @@ -57,7 +57,7 @@ add_also_request (GPtrArray *array, const char *item) } static void -add_hostname (GString *str, const char *format, const char *hostname) +add_hostname4 (GString *str, const char *format, const char *hostname) { char *plain_hostname, *dot; @@ -109,7 +109,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname) g_string_append (str, "; # added by NetworkManager\n"); } - add_hostname (str, HOSTNAME4_FORMAT "\n", hostname); + add_hostname4 (str, HOSTNAME4_FORMAT "\n", hostname); g_string_append_c (str, '\n'); @@ -125,13 +125,18 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname) } static void -add_ip6_config (GString *str, const char *hostname) +add_hostname6 (GString *str, const char *hostname) { - add_hostname (str, HOSTNAME6_FORMAT "\n", hostname); - g_string_append (str, - "send fqdn.encoded on;\n" - "send fqdn.no-client-update on;\n" - "send fqdn.server-update on;\n"); + /* dhclient only supports the fqdn.fqdn for DHCPv6 and requires a fully- + * qualified name for this option, so we must require one here too. + */ + if (hostname && strchr (hostname, '.')) { + g_string_append_printf (str, FQDN_FORMAT "\n", hostname); + g_string_append (str, + "send fqdn.encoded on;\n" + "send fqdn.server-update on;\n"); + g_string_append_c (str, '\n'); + } } static GBytes * @@ -232,7 +237,7 @@ nm_dhcp_dhclient_create_config (const char *interface, if (hostname) { if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0) continue; - if (strncmp (p, HOSTNAME6_TAG, strlen (HOSTNAME6_TAG)) == 0) + if (strncmp (p, FQDN_TAG, strlen (FQDN_TAG)) == 0) continue; } @@ -290,7 +295,7 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_c (new_contents, '\n'); if (is_ip6) { - add_ip6_config (new_contents, hostname); + add_hostname6 (new_contents, hostname); add_also_request (alsoreq, "dhcp6.name-servers"); add_also_request (alsoreq, "dhcp6.domain-search"); add_also_request (alsoreq, "dhcp6.client-id"); diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index 5aa25ff0..8cd4359a 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -140,6 +140,7 @@ process_dhclient_rfc3442_route (const char **octets, g_free (str_addr); goto error; } + g_free (str_addr); tmp_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp); route->network = tmp_addr; } diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h index ce1716b1..c316fb46 100644 --- a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h +++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h @@ -57,7 +57,7 @@ G_STMT_START { \ if (nm_logging_enabled (_l, LOGD_DHCP)) { \ const char *_location = strrchr (file "", '/'); \ \ - _nm_log (_location ? _location + 1 : file, line, func, _l, LOGD_DHCP, format, ## __VA_ARGS__); \ + _nm_log_impl (_location ? _location + 1 : file, line, func, _l, LOGD_DHCP, 0, format, ## __VA_ARGS__); \ } \ } G_STMT_END diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am index 9dc5dcb1..8aa79a29 100644 --- a/src/dhcp-manager/tests/Makefile.am +++ b/src/dhcp-manager/tests/Makefile.am @@ -37,6 +37,7 @@ test_dhcp_utils_LDADD = \ ################################# +@VALGRIND_RULES@ TESTS = test-dhcp-dhclient test-dhcp-utils EXTRA_DIST = \ diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in index c0324e30..e0a155f1 100644 --- a/src/dhcp-manager/tests/Makefile.in +++ b/src/dhcp-manager/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) TESTS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) subdir = src/dhcp-manager/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -200,6 +209,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -226,7 +237,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -261,6 +271,7 @@ 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@ @@ -518,7 +529,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/dhcp-manager/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/dhcp-manager/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -570,14 +580,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -917,6 +927,12 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +################################# + +@VALGRIND_RULES@ # 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/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 4f7e96af..e1a96cab 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -39,6 +39,7 @@ static void test_config (const char *orig, const char *expected, + gboolean ipv6, const char *hostname, const char *dhcp_client_id, GBytes *expected_new_client_id, @@ -55,7 +56,7 @@ test_config (const char *orig, } new = nm_dhcp_dhclient_create_config (iface, - FALSE, + ipv6, client_id, anycast_addr, hostname, @@ -103,7 +104,7 @@ static const char *orig_missing_expected = \ static void test_orig_missing (void) { - test_config (NULL, orig_missing_expected, NULL, NULL, NULL, "eth0", NULL); + test_config (NULL, orig_missing_expected, FALSE, NULL, NULL, NULL, "eth0", NULL); } /*******************************************/ @@ -132,7 +133,7 @@ static void test_override_client_id (void) { test_config (override_client_id_orig, override_client_id_expected, - NULL, + FALSE, NULL, "11:22:33:44:55:66", NULL, "eth0", @@ -161,7 +162,7 @@ static void test_quote_client_id (void) { test_config (NULL, quote_client_id_expected, - NULL, + FALSE, NULL, "1234", NULL, "eth0", @@ -190,7 +191,7 @@ static void test_ascii_client_id (void) { test_config (NULL, ascii_client_id_expected, - NULL, + FALSE, NULL, "qb:cd:ef:12:34:56", NULL, "eth0", @@ -219,7 +220,7 @@ static void test_hex_single_client_id (void) { test_config (NULL, hex_single_client_id_expected, - NULL, + FALSE, NULL, "ab:cd:e:12:34:56", NULL, "eth0", @@ -256,7 +257,7 @@ test_existing_hex_client_id (void) new_client_id = g_bytes_new (bytes, sizeof (bytes)); test_config (existing_hex_client_id_orig, existing_hex_client_id_expected, - NULL, + FALSE, NULL, NULL, new_client_id, "eth0", @@ -296,7 +297,7 @@ test_existing_ascii_client_id (void) memcpy (buf + 1, EACID, STRLEN (EACID)); new_client_id = g_bytes_new (buf, sizeof (buf)); test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected, - NULL, + FALSE, NULL, NULL, new_client_id, "eth0", @@ -329,7 +330,58 @@ static void test_override_hostname (void) { test_config (override_hostname_orig, override_hostname_expected, - "blahblah", + FALSE, "blahblah", + NULL, + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *override_hostname6_orig = \ + "send fqdn.fqdn \"foobar\";\n"; + +static const char *override_hostname6_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "send fqdn.fqdn \"blahblah.local\"; # added by NetworkManager\n" + "send fqdn.encoded on;\n" + "send fqdn.server-update on;\n" + "\n" + "also request dhcp6.name-servers;\n" + "also request dhcp6.domain-search;\n" + "also request dhcp6.client-id;\n" + "\n"; + +static void +test_override_hostname6 (void) +{ + test_config (override_hostname6_orig, override_hostname6_expected, + TRUE, "blahblah.local", + NULL, + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *nonfqdn_hostname6_expected = \ + "# Created by NetworkManager\n" + "\n" + "also request dhcp6.name-servers;\n" + "also request dhcp6.domain-search;\n" + "also request dhcp6.client-id;\n" + "\n"; + +static void +test_nonfqdn_hostname6 (void) +{ + /* Non-FQDN hostname can't be used with dhclient */ + test_config (NULL, nonfqdn_hostname6_expected, + TRUE, "blahblah", NULL, NULL, "eth0", @@ -364,7 +416,7 @@ static void test_existing_alsoreq (void) { test_config (existing_alsoreq_orig, existing_alsoreq_expected, - NULL, + FALSE, NULL, NULL, NULL, "eth0", @@ -403,7 +455,7 @@ static void test_existing_multiline_alsoreq (void) { test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected, - NULL, + FALSE, NULL, NULL, NULL, "eth0", @@ -430,6 +482,9 @@ test_one_duid (const char *escaped, const guint8 *unescaped, guint len) g_assert (w); g_assert_cmpint (strlen (escaped), ==, strlen (w)); g_assert_cmpstr (escaped, ==, w); + + g_byte_array_free (t, TRUE); + g_free (w); } static void @@ -718,6 +773,8 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id); g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id); g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname); + g_test_add_func ("/dhcp/dhclient/override_hostname6", test_override_hostname6); + g_test_add_func ("/dhcp/dhclient/nonfqdn_hostname6", test_nonfqdn_hostname6); g_test_add_func ("/dhcp/dhclient/existing_alsoreq", test_existing_alsoreq); g_test_add_func ("/dhcp/dhclient/existing_multiline_alsoreq", test_existing_multiline_alsoreq); g_test_add_func ("/dhcp/dhclient/duids", test_duids); diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c index 4ff8caad..53688a5b 100644 --- a/src/dhcp-manager/tests/test-dhcp-utils.c +++ b/src/dhcp-manager/tests/test-dhcp-utils.c @@ -694,8 +694,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv); - nm_logging_setup ("WARN", "DEFAULT", NULL, NULL); + nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); g_test_add_func ("/dhcp/generic-options", test_generic_options); g_test_add_func ("/dhcp/wins-options", test_wins_options); diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 0d93d8bb..2f8ceab5 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -28,6 +28,8 @@ #include <resolv.h> #include <stdlib.h> #include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> #include <linux/fs.h> @@ -279,10 +281,10 @@ dispatch_netconfig (char **searches, char **nis_servers, GError **error) { - char *str, *tmp; + char *str; GPid pid; gint fd; - int ret; + int ret = 1; pid = run_netconfig (error, &fd); if (pid < 0) @@ -321,12 +323,18 @@ dispatch_netconfig (char **searches, again: - ret = waitpid (pid, NULL, 0); - if (ret < 0 && errno == EINTR) - goto again; - else if (ret < 0 && errno == ECHILD) { - /* When the netconfig exist, the errno is ECHILD, it should return TRUE */ - return TRUE; + if (waitpid (pid, NULL, 0) < 0) { + if (errno == EINTR) + goto again; + else if (errno == ECHILD) { + /* child already exited */ + ret = pid; + } else { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + "Error waiting for netconfig to exit: %s", + strerror (errno)); + ret = 0; + } } return ret > 0; @@ -342,22 +350,12 @@ write_resolv_conf (FILE *f, { char *searches_str = NULL; char *nameservers_str = NULL; - int i; gboolean retval = FALSE; + char *tmp_str; GString *str; - - if (fprintf (f, "%s","# Generated by NetworkManager\n") < 0) { - g_set_error (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_FAILED, - "Could not write " _PATH_RESCONF ": %s\n", - g_strerror (errno)); - return FALSE; - } + int i; if (searches) { - char *tmp_str; - tmp_str = g_strjoinv (" ", searches); searches_str = g_strconcat ("search ", tmp_str, "\n", NULL); g_free (tmp_str); @@ -385,10 +383,17 @@ write_resolv_conf (FILE *f, nameservers_str = g_string_free (str, FALSE); - if (fprintf (f, "%s%s", + if (fprintf (f, "# Generated by NetworkManager\n%s%s", searches_str ? searches_str : "", - strlen (nameservers_str) ? nameservers_str : "") != -1) + nameservers_str) > 0) retval = TRUE; + else { + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Could not write " _PATH_RESCONF ": %s\n", + g_strerror (errno)); + } g_free (searches_str); g_free (nameservers_str); @@ -405,9 +410,15 @@ dispatch_resolvconf (char **searches, char *cmd; FILE *f; gboolean retval = FALSE; + int errnosv, err; - if (! g_file_test (RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) + if (!g_file_test (RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) { + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + RESOLVCONF_PATH " is not executable"); return FALSE; + } if (searches || nameservers) { cmd = g_strconcat (RESOLVCONF_PATH, " -a ", "NetworkManager", NULL); @@ -421,12 +432,21 @@ dispatch_resolvconf (char **searches, g_strerror (errno)); else { retval = write_resolv_conf (f, searches, nameservers, error); - retval &= (pclose (f) == 0); + err = pclose (f); + if (err < 0) { + errnosv = errno; + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errnosv), + "Failed to close pipe to resolvconf: %d", errnosv); + retval = FALSE; + } else if (err > 0) { + nm_log_warn (LOGD_DNS, "resolvconf failed with status %d", err); + retval = FALSE; + } } } else { cmd = g_strconcat (RESOLVCONF_PATH, " -d ", "NetworkManager", NULL); nm_log_info (LOGD_DNS, "Removing DNS information from %s", RESOLVCONF_PATH); - if (nm_spawn_process (cmd) == 0) + if (nm_spawn_process (cmd, error) == 0) retval = TRUE; } @@ -559,6 +579,42 @@ compute_hash (NMDnsManager *self, guint8 buffer[HASH_LEN]) g_checksum_free (sum); } +static void +build_plugin_config_lists (NMDnsManager *self, + GSList **out_vpn_configs, + GSList **out_dev_configs, + GSList **out_other_configs) +{ + NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + GSList *iter; + + g_return_if_fail (out_vpn_configs && !*out_vpn_configs); + g_return_if_fail (out_dev_configs && !*out_dev_configs); + g_return_if_fail (out_other_configs && !*out_other_configs); + + /* Build up config lists for plugins; we use the raw configs here, not the + * merged information that we write to resolv.conf so that the plugins can + * still use the domain information in each config to provide split DNS if + * they want to. + */ + if (priv->ip4_vpn_config) + *out_vpn_configs = g_slist_append (*out_vpn_configs, priv->ip4_vpn_config); + if (priv->ip6_vpn_config) + *out_vpn_configs = g_slist_append (*out_vpn_configs, priv->ip6_vpn_config); + if (priv->ip4_device_config) + *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip4_device_config); + if (priv->ip6_device_config) + *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip6_device_config); + + for (iter = priv->configs; iter; iter = g_slist_next (iter)) { + if ( (iter->data != priv->ip4_vpn_config) + && (iter->data != priv->ip4_device_config) + && (iter->data != priv->ip6_vpn_config) + && (iter->data != priv->ip6_device_config)) + *out_other_configs = g_slist_append (*out_other_configs, iter->data); + } +} + static gboolean update_dns (NMDnsManager *self, gboolean no_caching, @@ -566,7 +622,7 @@ update_dns (NMDnsManager *self, { NMDnsManagerPrivate *priv; NMResolvConfData rc; - GSList *iter, *vpn_configs = NULL, *dev_configs = NULL, *other_configs = NULL; + GSList *iter; const char *nis_domain = NULL; char **searches = NULL; char **nameservers = NULL; @@ -574,8 +630,7 @@ update_dns (NMDnsManager *self, int num, i, len; gboolean success = FALSE, caching = FALSE; - g_return_val_if_fail (error != NULL, FALSE); - g_return_val_if_fail (*error == NULL, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); priv = NM_DNS_MANAGER_GET_PRIVATE (self); @@ -672,32 +727,11 @@ update_dns (NMDnsManager *self, nis_domain = rc.nis_domain; - /* Build up config lists for plugins; we use the raw configs here, not the - * merged information that we write to resolv.conf so that the plugins can - * still use the domain information in each config to provide split DNS if - * they want to. - */ - if (priv->ip4_vpn_config) - vpn_configs = g_slist_append (vpn_configs, priv->ip4_vpn_config); - if (priv->ip6_vpn_config) - vpn_configs = g_slist_append (vpn_configs, priv->ip6_vpn_config); - if (priv->ip4_device_config) - dev_configs = g_slist_append (dev_configs, priv->ip4_device_config); - if (priv->ip6_device_config) - dev_configs = g_slist_append (dev_configs, priv->ip6_device_config); - - for (iter = priv->configs; iter; iter = g_slist_next (iter)) { - if ( (iter->data != priv->ip4_vpn_config) - && (iter->data != priv->ip4_device_config) - && (iter->data != priv->ip6_vpn_config) - && (iter->data != priv->ip6_device_config)) - other_configs = g_slist_append (other_configs, iter->data); - } - /* Let any plugins do their thing first */ if (priv->plugin) { NMDnsPlugin *plugin = priv->plugin; const char *plugin_name = nm_dns_plugin_get_name (plugin); + GSList *vpn_configs = NULL, *dev_configs = NULL, *other_configs = NULL; if (nm_dns_plugin_is_caching (plugin)) { if (no_caching) { @@ -708,6 +742,8 @@ update_dns (NMDnsManager *self, caching = TRUE; } + build_plugin_config_lists (self, &vpn_configs, &dev_configs, &other_configs); + nm_log_dbg (LOGD_DNS, "DNS: updating plugin %s", plugin_name); if (!nm_dns_plugin_update (plugin, vpn_configs, @@ -721,15 +757,14 @@ update_dns (NMDnsManager *self, */ caching = FALSE; } + g_slist_free (vpn_configs); + g_slist_free (dev_configs); + g_slist_free (other_configs); skip: ; } - g_slist_free (vpn_configs); - g_slist_free (dev_configs); - g_slist_free (other_configs); - /* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf * to ensure that the glibc resolver doesn't try to round-robin nameservers, * but only uses the local caching nameserver. @@ -781,9 +816,23 @@ plugin_failed (NMDnsPlugin *plugin, gpointer user_data) /* Disable caching until the next DNS update */ if (!update_dns (self, TRUE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); + g_clear_error (&error); + } +} + +static void +plugin_child_quit (NMDnsPlugin *plugin, int exit_status, gpointer user_data) +{ + NMDnsManager *self = NM_DNS_MANAGER (user_data); + GError *error = NULL; + + nm_log_warn (LOGD_DNS, "DNS: plugin %s child quit unexpectedly; refreshing DNS", + nm_dns_plugin_get_name (plugin)); + + /* Let the plugin try to spawn the child again */ + if (!update_dns (self, FALSE, &error)) { + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } } @@ -820,9 +869,7 @@ nm_dns_manager_add_ip4_config (NMDnsManager *mgr, priv->configs = g_slist_append (priv->configs, g_object_ref (config)); if (!priv->updates_queue && !update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -854,9 +901,7 @@ nm_dns_manager_remove_ip4_config (NMDnsManager *mgr, NMIP4Config *config) g_object_unref (config); if (!priv->updates_queue && !update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -897,9 +942,7 @@ nm_dns_manager_add_ip6_config (NMDnsManager *mgr, priv->configs = g_slist_append (priv->configs, g_object_ref (config)); if (!priv->updates_queue && !update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -931,9 +974,7 @@ nm_dns_manager_remove_ip6_config (NMDnsManager *mgr, NMIP6Config *config) g_object_unref (config); if (!priv->updates_queue && !update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -975,9 +1016,7 @@ nm_dns_manager_set_hostname (NMDnsManager *mgr, priv->hostname = g_strdup (filtered); if (!priv->updates_queue && !update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } } @@ -1031,9 +1070,7 @@ nm_dns_manager_end_updates (NMDnsManager *mgr, const char *func) /* Commit all the outstanding changes */ nm_log_dbg (LOGD_DNS, "(%s): committing DNS changes (%d)", func, priv->updates_queue); if (!update_dns (mgr, FALSE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1105,6 +1142,7 @@ nm_dns_manager_init (NMDnsManager *self) if (priv->plugin) { nm_log_info (LOGD_DNS, "DNS: loaded plugin %s", nm_dns_plugin_get_name (priv->plugin)); g_signal_connect (priv->plugin, NM_DNS_PLUGIN_FAILED, G_CALLBACK (plugin_failed), self); + g_signal_connect (priv->plugin, NM_DNS_PLUGIN_CHILD_QUIT, G_CALLBACK (plugin_child_quit), self); } } @@ -1115,7 +1153,11 @@ dispose (GObject *object) NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); GError *error = NULL; - g_clear_object (&priv->plugin); + if (priv->plugin) { + g_signal_handlers_disconnect_by_func (priv->plugin, plugin_failed, self); + g_signal_handlers_disconnect_by_func (priv->plugin, plugin_child_quit, self); + g_clear_object (&priv->plugin); + } /* If we're quitting, leave a valid resolv.conf in place, not one * pointing to 127.0.0.1 if any plugins were active. Thus update @@ -1123,9 +1165,7 @@ dispose (GObject *object) * DNS updates yet, there's no reason to touch resolv.conf on shutdown. */ if (priv->dns_touched && !update_dns (self, TRUE, &error)) { - nm_log_warn (LOGD_DNS, "could not commit DNS changes on shutdown: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + nm_log_warn (LOGD_DNS, "could not commit DNS changes on shutdown: %s", error->message); g_clear_error (&error); priv->dns_touched = FALSE; } diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c index b083b105..c684464e 100644 --- a/src/dns-manager/nm-dns-plugin.c +++ b/src/dns-manager/nm-dns-plugin.c @@ -198,7 +198,8 @@ nm_dns_plugin_child_spawn (NMDnsPlugin *self, return priv->pid; } -gboolean nm_dns_plugin_child_kill (NMDnsPlugin *self) +gboolean +nm_dns_plugin_child_kill (NMDnsPlugin *self) { NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self); @@ -208,7 +209,7 @@ gboolean nm_dns_plugin_child_kill (NMDnsPlugin *self) } if (priv->pid) { - nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_DNS, priv->progname, 2000, NULL, NULL); + nm_utils_kill_child_sync (priv->pid, SIGTERM, LOGD_DNS, priv->progname, NULL, 1000, 0); priv->pid = 0; g_free (priv->progname); priv->progname = NULL; diff --git a/src/dns-manager/nm-dns-unbound.c b/src/dns-manager/nm-dns-unbound.c index 533290c1..5723bf82 100644 --- a/src/dns-manager/nm-dns-unbound.c +++ b/src/dns-manager/nm-dns-unbound.c @@ -42,7 +42,7 @@ update (NMDnsPlugin *plugin, * without calling custom scripts. The dnssec-trigger functionality * may be eventually merged into NetworkManager. */ - return nm_spawn_process ("/usr/libexec/dnssec-trigger-script --async --update") == 0; + return nm_spawn_process ("/usr/libexec/dnssec-trigger-script --async --update", NULL) == 0; } static gboolean diff --git a/src/dnsmasq-manager/tests/Makefile.am b/src/dnsmasq-manager/tests/Makefile.am index c6ce1cda..b51de6aa 100644 --- a/src/dnsmasq-manager/tests/Makefile.am +++ b/src/dnsmasq-manager/tests/Makefile.am @@ -19,5 +19,6 @@ test_dnsmasq_utils_SOURCES = \ test_dnsmasq_utils_LDADD = \ $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-dnsmasq-utils diff --git a/src/dnsmasq-manager/tests/Makefile.in b/src/dnsmasq-manager/tests/Makefile.in index d5f92416..c21629db 100644 --- a/src/dnsmasq-manager/tests/Makefile.in +++ b/src/dnsmasq-manager/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ noinst_PROGRAMS = test-dnsmasq-utils$(EXEEXT) TESTS = test-dnsmasq-utils$(EXEEXT) subdir = src/dnsmasq-manager/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -194,6 +203,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -220,7 +231,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -255,6 +265,7 @@ 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@ @@ -490,7 +501,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/dnsmasq-manager/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/dnsmasq-manager/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -535,14 +545,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -854,6 +864,10 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +@VALGRIND_RULES@ # 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/src/main-utils.c b/src/main-utils.c index 0fa3644f..c4d0eeb9 100644 --- a/src/main-utils.c +++ b/src/main-utils.c @@ -33,8 +33,10 @@ #include <glib/gi18n.h> #include <gmodule.h> +#include "gsystem-local-alloc.h" #include "main-utils.h" #include "nm-posix-signals.h" +#include "NetworkManagerUtils.h" #include "nm-logging.h" static sigset_t signal_set; @@ -152,72 +154,82 @@ nm_main_utils_write_pidfile (const char *pidfile) return success; } +void +nm_main_utils_ensure_rundir () +{ + /* Setup runtime directory */ + if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) { + fprintf (stderr, _("Cannot create '%s': %s"), NMRUNDIR, strerror (errno)); + exit (1); + } +} + /** - * nm_main_utils_check_pidfile: + * nm_main_utils_ensure_not_running_pidfile: * @pidfile: the pid file - * @name: the process name * * Checks whether the pidfile already exists and contains PID of a running * process. * - * Returns: %TRUE if the specified pidfile already exists and contains the PID - * of a running process named @name, or %FALSE if not + * Exits with code 1 if a conflicting process is running. */ -gboolean -nm_main_utils_check_pidfile (const char *pidfile, const char *name) +void +nm_main_utils_ensure_not_running_pidfile (const char *pidfile) { - char *contents = NULL; + gs_free char *contents = NULL; + gs_free char *proc_cmdline = NULL; gsize len = 0; glong pid; - char *proc_cmdline = NULL; - gboolean nm_running = FALSE; const char *process_name; + const char *prgname = g_get_prgname (); - /* Setup runtime directory */ - if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) { - nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMRUNDIR, strerror (errno)); - exit (1); - } + g_return_if_fail (prgname); - if (!g_file_get_contents (pidfile, &contents, &len, NULL)) - return FALSE; + if (!pidfile || !*pidfile) + return; + if (!g_file_get_contents (pidfile, &contents, &len, NULL)) + return; if (len <= 0) - goto done; + return; errno = 0; pid = strtol (contents, NULL, 10); if (pid <= 0 || pid > 65536 || errno) - goto done; + return; - g_free (contents); + g_clear_pointer (&contents, g_free); proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid); if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL)) - goto done; + return; process_name = strrchr (contents, '/'); if (process_name) process_name++; else process_name = contents; - if (strcmp (process_name, name) == 0) { + if (strcmp (process_name, prgname) == 0) { /* Check that the process exists */ if (kill (pid, 0) == 0) { - fprintf (stderr, _("%s is already running (pid %ld)\n"), name, pid); - nm_running = TRUE; + fprintf (stderr, _("%s is already running (pid %ld)\n"), prgname, pid); + exit (1); } } +} -done: - g_free (proc_cmdline); - g_free (contents); - return nm_running; +void +nm_main_utils_ensure_root () +{ + if (getuid () != 0) { + fprintf (stderr, _("You must be root to run %s!\n"), str_if_set (g_get_prgname (), "")); + exit (1); + } } gboolean nm_main_utils_early_setup (const char *progname, - char **argv[], int *argc, + char **argv[], GOptionEntry *options, GOptionEntry *more_options, const char *summary) @@ -226,6 +238,8 @@ nm_main_utils_early_setup (const char *progname, GError *error = NULL; gboolean success = FALSE; int i; + const char *opt_fmt_log_level = NULL, *opt_fmt_log_domains = NULL; + const char **opt_loc_log_level = NULL, **opt_loc_log_domains = NULL; /* Make GIO ignore the remote VFS service; otherwise it tries to use the * session bus to contact the remote service, and NM shouldn't ever be @@ -244,16 +258,16 @@ nm_main_utils_early_setup (const char *progname, setlocale (LC_ALL, ""); textdomain (GETTEXT_PACKAGE); - if (getuid () != 0) { - fprintf (stderr, _("You must be root to run %s!\n"), progname); - exit (1); - } - for (i = 0; options[i].long_name; i++) { - if (!strcmp (options[i].long_name, "log-level")) + if (!strcmp (options[i].long_name, "log-level")) { + opt_fmt_log_level = options[i].description; + opt_loc_log_level = &options[i].description; options[i].description = g_strdup_printf (options[i].description, nm_logging_all_levels_to_string ()); - else if (!strcmp (options[i].long_name, "log-domains")) + } else if (!strcmp (options[i].long_name, "log-domains")) { + opt_fmt_log_domains = options[i].description; + opt_loc_log_domains = &options[i].description; options[i].description = g_strdup_printf (options[i].description, nm_logging_all_domains_to_string ()); + } } /* Parse options */ @@ -274,6 +288,15 @@ nm_main_utils_early_setup (const char *progname, } g_option_context_free (opt_ctx); + if (opt_loc_log_level) { + g_free ((char *) *opt_loc_log_level); + *opt_loc_log_level = opt_fmt_log_level; + } + if (opt_loc_log_domains) { + g_free ((char *) *opt_loc_log_domains); + *opt_loc_log_domains = opt_fmt_log_domains; + } + return success; } diff --git a/src/main-utils.h b/src/main-utils.h index 472fa5e7..1fceb350 100644 --- a/src/main-utils.h +++ b/src/main-utils.h @@ -23,15 +23,19 @@ #include <glib.h> +void nm_main_utils_ensure_root (void); + gboolean nm_main_utils_setup_signals (GMainLoop *main_loop, gboolean *quit_early_ptr); +void nm_main_utils_ensure_rundir (void); + gboolean nm_main_utils_write_pidfile (const char *pidfile); -gboolean nm_main_utils_check_pidfile (const char *pidfile, const char *name); +void nm_main_utils_ensure_not_running_pidfile (const char *pidfile); gboolean nm_main_utils_early_setup (const char *progname, - char **argv[], int *argc, + char **argv[], GOptionEntry *options, GOptionEntry *more_options, const char *summary); diff --git a/src/main.c b/src/main.c index b3206fb4..53e829cd 100644 --- a/src/main.c +++ b/src/main.c @@ -69,6 +69,21 @@ #define NM_DEFAULT_SYSTEM_STATE_FILE NMSTATEDIR "/NetworkManager.state" static GMainLoop *main_loop = NULL; +static gboolean quit_early = FALSE; + +static struct { + gboolean show_version; + gboolean become_daemon; + gboolean debug; + gboolean g_fatal_warnings; + gboolean run_from_build_dir; + char *opt_log_level; + char *opt_log_domains; + char *pidfile; + char *state_file; +} global_opt = { + .become_daemon = TRUE, +}; static gboolean parse_state_file (const char *filename, @@ -149,11 +164,23 @@ parse_state_file (const char *filename, } static void +_set_g_fatal_warnings () +{ + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); +} + +static void _init_nm_debug (const char *debug) { const guint D_RLIMIT_CORE = 1; + const guint D_FATAL_WARNINGS = 2; GDebugKey keys[] = { { "RLIMIT_CORE", D_RLIMIT_CORE }, + { "fatal-warnings", D_FATAL_WARNINGS }, }; guint flags = 0; const char *env = getenv ("NM_DEBUG"); @@ -167,7 +194,7 @@ _init_nm_debug (const char *debug) if (debug && strcasecmp (debug, "help") != 0) flags |= g_parse_debug_string (debug, keys, G_N_ELEMENTS (keys)); - if (flags & D_RLIMIT_CORE) { + if (NM_FLAGS_HAS (flags, D_RLIMIT_CORE)) { /* only enable this, if explicitly requested, because it might * expose sensitive data. */ @@ -177,6 +204,8 @@ _init_nm_debug (const char *debug) }; setrlimit (RLIMIT_CORE, &limit); } + if (NM_FLAGS_HAS (flags, D_FATAL_WARNINGS)) + _set_g_fatal_warnings (); } static void @@ -184,6 +213,37 @@ manager_configure_quit (NMManager *manager, gpointer user_data) { nm_log_info (LOGD_CORE, "quitting now that startup is complete"); g_main_loop_quit (main_loop); + quit_early = TRUE; +} + +static void +do_early_setup (int *argc, char **argv[]) +{ + GOptionEntry options[] = { + { "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL }, + { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL }, + { "debug", 'd', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), NULL }, + { "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" }, + { "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains, + N_("Log domains separated by ',': any combination of [%s]"), + "PLATFORM,RFKILL,WIFI" }, + { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL }, + { "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &global_opt.pidfile, N_("Specify the location of a PID file"), N_("filename") }, + { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &global_opt.state_file, N_("State file location"), N_("/path/to/state.file") }, + { "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &global_opt.run_from_build_dir, "Run from build directory", NULL }, + {NULL} + }; + + if (!nm_main_utils_early_setup ("NetworkManager", + argc, + argv, + options, + nm_config_get_options (), + _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with."))) + exit (1); + + global_opt.pidfile = global_opt.pidfile ? global_opt.pidfile : g_strdup (NM_DEFAULT_PID_FILE); + global_opt.state_file = global_opt.state_file ? global_opt.state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE); } /* @@ -193,19 +253,11 @@ manager_configure_quit (NMManager *manager, gpointer user_data) int main (int argc, char *argv[]) { - char *opt_log_level = NULL; - char *opt_log_domains = NULL; - gboolean become_daemon = TRUE, run_from_build_dir = FALSE; - gboolean debug = FALSE; - gboolean g_fatal_warnings = FALSE; - gs_free char *pidfile = NULL; - gs_free char *state_file = NULL; gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; - gboolean success, show_version = FALSE; + gboolean success = FALSE; NMManager *manager = NULL; gs_unref_object NMVpnManager *vpn_manager = NULL; gs_unref_object NMDnsManager *dns_mgr = NULL; - gs_unref_object NMDBusManager *dbus_mgr = NULL; gs_unref_object NMSupplicantManager *sup_mgr = NULL; gs_unref_object NMDhcpManager *dhcp_mgr = NULL; gs_unref_object NMFirewallManager *fw_mgr = NULL; @@ -215,58 +267,40 @@ main (int argc, char *argv[]) GError *error = NULL; gboolean wrote_pidfile = FALSE; char *bad_domains = NULL; - gboolean quit_early = FALSE; - GOptionEntry options[] = { - { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL }, - { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL }, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL }, - { "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" }, - { "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains, - N_("Log domains separated by ',': any combination of [%s]"), - "PLATFORM,RFKILL,WIFI" }, - { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL }, - { "pid-file", 'p', 0, G_OPTION_ARG_FILENAME, &pidfile, N_("Specify the location of a PID file"), N_("filename") }, - { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, N_("State file location"), N_("/path/to/state.file") }, - { "run-from-build-dir", 0, 0, G_OPTION_ARG_NONE, &run_from_build_dir, "Run from build directory", NULL }, - {NULL} - }; +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif _nm_utils_is_manager_process = TRUE; main_loop = g_main_loop_new (NULL, FALSE); - if (!nm_main_utils_early_setup ("NetworkManager", - &argv, - &argc, - options, - nm_config_get_options (), - _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with."))) - exit (1); + do_early_setup (&argc, &argv); + + if (global_opt.g_fatal_warnings) + _set_g_fatal_warnings (); - if (show_version) { + if (global_opt.show_version) { fprintf (stdout, NM_DIST_VERSION "\n"); exit (0); } - if (!nm_logging_setup (opt_log_level, - opt_log_domains, - &bad_domains, - &error)) { - fprintf (stderr, - _("%s. Please use --help to see a list of valid options.\n"), - error->message); + nm_main_utils_ensure_root (); + + nm_main_utils_ensure_not_running_pidfile (global_opt.pidfile); + + /* Ensure state directory exists */ + if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) { + fprintf (stderr, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno)); exit (1); - } else if (bad_domains) { - fprintf (stderr, - _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"), - bad_domains); - g_clear_pointer (&bad_domains, g_free); } + nm_main_utils_ensure_rundir (); + /* When running from the build directory, determine our build directory * base and set helper paths in the build tree */ - if (run_from_build_dir) { + if (global_opt.run_from_build_dir) { char *path, *slash; int g; @@ -288,19 +322,21 @@ main (int argc, char *argv[]) g_free (path); } - /* Ensure state directory exists */ - if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) { - nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno)); + if (!nm_logging_setup (global_opt.opt_log_level, + global_opt.opt_log_domains, + &bad_domains, + &error)) { + fprintf (stderr, + _("%s. Please use --help to see a list of valid options.\n"), + error->message); exit (1); + } else if (bad_domains) { + fprintf (stderr, + _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"), + bad_domains); + g_clear_pointer (&bad_domains, g_free); } - pidfile = pidfile ? pidfile : g_strdup (NM_DEFAULT_PID_FILE); - state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE); - - /* check pid file */ - if (nm_main_utils_check_pidfile (pidfile, "NetworkManager")) - exit (1); - /* Read the config file and CLI overrides */ config = nm_config_new (&error); if (config == NULL) { @@ -310,10 +346,12 @@ main (int argc, char *argv[]) exit (1); } + _init_nm_debug (nm_config_get_debug (config)); + /* Initialize logging from config file *only* if not explicitly * specified by commandline. */ - if (opt_log_level == NULL && opt_log_domains == NULL) { + if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) { if (!nm_logging_setup (nm_config_get_log_level (config), nm_config_get_log_domains (config), &bad_domains, @@ -329,17 +367,7 @@ main (int argc, char *argv[]) } } - /* Parse the state file */ - if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) { - fprintf (stderr, _("State file %s parsing failed: (%d) %s\n"), - state_file, - error ? error->code : -1, - (error && error->message) ? error->message : _("unknown")); - /* Not a hard failure */ - } - g_clear_error (&error); - - if (become_daemon && !debug) { + if (global_opt.become_daemon && !global_opt.debug) { if (daemon (0, 0) < 0) { int saved_errno; @@ -349,28 +377,26 @@ main (int argc, char *argv[]) saved_errno); exit (1); } - wrote_pidfile = nm_main_utils_write_pidfile (pidfile); + wrote_pidfile = nm_main_utils_write_pidfile (global_opt.pidfile); } - _init_nm_debug (nm_config_get_debug (config)); - /* Set up unix signal handling - before creating threads, but after daemonizing! */ if (!nm_main_utils_setup_signals (main_loop, &quit_early)) exit (1); - if (g_fatal_warnings) { - GLogLevelFlags fatal_mask; + nm_logging_syslog_openlog (global_opt.debug); - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - nm_logging_syslog_openlog (debug); + nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting..."); -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + /* Parse the state file */ + if (!parse_state_file (global_opt.state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) { + nm_log_err (LOGD_CORE, "State file %s parsing failed: (%d) %s", + global_opt.state_file, + error ? error->code : -1, + (error && error->message) ? error->message : _("unknown")); + /* Not a hard failure */ + } + g_clear_error (&error); dbus_threads_init_default (); @@ -379,9 +405,6 @@ main (int argc, char *argv[]) */ dbus_glib_global_set_disable_legacy_property_access (); - nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting..."); - success = FALSE; - nm_log_info (LOGD_CORE, "Read config: %s", nm_config_get_description (config)); nm_log_info (LOGD_CORE, "WEXT support is %s", #if HAVE_WEXT @@ -391,15 +414,26 @@ main (int argc, char *argv[]) #endif ); + if (!nm_dbus_manager_get_connection (nm_dbus_manager_get ())) { +#if HAVE_DBUS_GLIB_100 + nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available"); +#else + nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting..."); + goto done; +#endif + } else { + /* Start our DBus service */ + if (!nm_dbus_manager_start_service (nm_dbus_manager_get ())) { + nm_log_err (LOGD_CORE, "failed to start the dbus service."); + goto done; + } + } + /* Set up platform interaction layer */ nm_linux_platform_setup (); nm_auth_manager_setup (nm_config_get_auth_polkit (config)); - /* Initialize our DBus service & connection */ - dbus_mgr = nm_dbus_manager_get (); - g_assert (dbus_mgr != NULL); - vpn_manager = nm_vpn_manager_get (); g_assert (vpn_manager != NULL); @@ -420,7 +454,7 @@ main (int argc, char *argv[]) } manager = nm_manager_new (settings, - state_file, + global_opt.state_file, net_enabled, wifi_enabled, wwan_enabled, @@ -444,21 +478,6 @@ main (int argc, char *argv[]) session_monitor = nm_session_monitor_get (); g_assert (session_monitor != NULL); - if (!nm_dbus_manager_get_connection (dbus_mgr)) { -#if HAVE_DBUS_GLIB_100 - nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available"); -#else - nm_log_err (LOGD_CORE, "Failed to connect to D-Bus, exiting..."); - goto done; -#endif - } else { - /* Start our DBus service */ - if (!nm_dbus_manager_start_service (dbus_mgr)) { - nm_log_err (LOGD_CORE, "failed to start the dbus service."); - goto done; - } - } - g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config); nm_manager_start (manager); @@ -489,8 +508,8 @@ done: nm_logging_syslog_closelog (); - if (pidfile && wrote_pidfile) - unlink (pidfile); + if (global_opt.pidfile && wrote_pidfile) + unlink (global_opt.pidfile); nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error"); exit (success ? 0 : 1); diff --git a/src/nm-auth-manager.c b/src/nm-auth-manager.c index fc8f8cda..8bd167ef 100644 --- a/src/nm-auth-manager.c +++ b/src/nm-auth-manager.c @@ -37,11 +37,11 @@ if (nm_logging_enabled ((level), (domain))) { \ char __prefix[30] = "auth"; \ \ - if ((self) != _instance) \ + if ((self) != singleton_instance) \ g_snprintf (__prefix, sizeof (__prefix), "auth[%p]", (self)); \ - nm_log ((level), (domain), \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + _nm_log ((level), (domain), 0, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } \ } G_STMT_END @@ -76,7 +76,7 @@ typedef struct { #endif } NMAuthManagerPrivate; -static NMAuthManager *_instance = NULL; +static NMAuthManager *singleton_instance = NULL; G_DEFINE_TYPE (NMAuthManager, nm_auth_manager, G_TYPE_OBJECT) @@ -485,9 +485,9 @@ _dbus_new_proxy_cb (GObject *source_object, NMAuthManager * nm_auth_manager_get () { - g_return_val_if_fail (_instance, NULL); + g_return_val_if_fail (singleton_instance, NULL); - return _instance; + return singleton_instance; } NMAuthManager * @@ -495,14 +495,14 @@ nm_auth_manager_setup (gboolean polkit_enabled) { NMAuthManager *self; - g_return_val_if_fail (!_instance, _instance); + g_return_val_if_fail (!singleton_instance, singleton_instance); self = g_object_new (NM_TYPE_AUTH_MANAGER, NM_AUTH_MANAGER_POLKIT_ENABLED, polkit_enabled, NULL); _LOGD ("set instance"); - return (_instance = self); + return (singleton_instance = self); } /*****************************************************************************/ @@ -616,8 +616,8 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_auth_manager_parent_class)->finalize (object); - if (self == _instance) { - _instance = NULL; + if (self == singleton_instance) { + singleton_instance = NULL; _LOGD ("unset instance"); } } diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c index 209f98e1..13133f27 100644 --- a/src/nm-auth-subject.c +++ b/src/nm-auth-subject.c @@ -38,6 +38,7 @@ #include "nm-enum-types.h" #include "nm-glib-compat.h" #include "NetworkManagerUtils.h" +#include "gsystem-local-alloc.h" G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT) @@ -175,7 +176,7 @@ _new_unix_process (DBusGMethodInvocation *context, NMAuthSubject *self; gboolean success = FALSE; gulong pid = 0, uid = 0; - char *dbus_sender = NULL; + gs_free char *dbus_sender = NULL; g_return_val_if_fail (context || (connection && message), NULL); diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index 9ace1629..b2ca800c 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -158,17 +158,18 @@ nm_auth_chain_steal_data (NMAuthChain *self, const char *tag) { ChainData *tmp; gpointer value = NULL; + void *orig_key; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (tag != NULL, NULL); - tmp = g_hash_table_lookup (self->data, tag); - if (tmp) { + if (g_hash_table_lookup_extended (self->data, tag, &orig_key, (gpointer)&tmp)) { g_hash_table_steal (self->data, tag); value = tmp->data; /* Make sure the destroy handler isn't called when freeing */ tmp->destroy = NULL; free_data (tmp); + g_free (orig_key); } return value; } diff --git a/src/nm-config.c b/src/nm-config.c index e8cb0864..4626ae26 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -275,14 +275,18 @@ merge_no_auto_default_state (NMConfig *config) if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) { list = g_strsplit (data, "\n", -1); for (i = 0; list[i]; i++) { - if (!*list[i]) + if (!*list[i]) { + g_free (list[i]); continue; + } for (j = 0; j < updated->len; j++) { if (!strcmp (list[i], updated->pdata[j])) break; } if (j == updated->len) g_ptr_array_add (updated, list[i]); + else + g_free (list[i]); } g_free (list); g_free (data); @@ -403,10 +407,12 @@ read_config (NMConfig *config, const char *path, GError **error) continue; for (k = 0; keys[k]; k++) { int len = strlen (keys[k]); + char *v; + if (keys[k][len - 1] == '+') { char *base_key = g_strndup (keys[k], len - 1); - const char *old_val = g_key_file_get_value (priv->keyfile, groups[g], base_key, NULL); - const char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL); + char *old_val = g_key_file_get_value (priv->keyfile, groups[g], base_key, NULL); + char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL); if (old_val && *old_val) { char *combined = g_strconcat (old_val, ",", new_val, NULL); @@ -417,13 +423,18 @@ read_config (NMConfig *config, const char *path, GError **error) g_key_file_set_value (priv->keyfile, groups[g], base_key, new_val); g_free (base_key); + g_free (old_val); + g_free (new_val); continue; } g_key_file_set_value (priv->keyfile, groups[g], keys[k], - g_key_file_get_value (kf, groups[g], keys[k], NULL)); + v = g_key_file_get_value (kf, groups[g], keys[k], NULL)); + g_free (v); } + g_strfreev (keys); } + g_strfreev (groups); g_key_file_free (kf); return TRUE; diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index 8a324a5c..85bd70ae 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -44,7 +44,7 @@ typedef struct { #if WITH_CONCHECK SoupSession *soup_session; - gboolean running; + guint pending_checks; guint check_id; #endif @@ -69,12 +69,33 @@ nm_connectivity_get_state (NMConnectivity *connectivity) return NM_CONNECTIVITY_GET_PRIVATE (connectivity)->state; } +static const char * +state_name (NMConnectivityState state) +{ + switch (state) { + case NM_CONNECTIVITY_UNKNOWN: + return "UNKNOWN"; + case NM_CONNECTIVITY_NONE: + return "NONE"; + case NM_CONNECTIVITY_LIMITED: + return "LIMITED"; + case NM_CONNECTIVITY_PORTAL: + return "PORTAL"; + case NM_CONNECTIVITY_FULL: + return "FULL"; + default: + return "???"; + } +} + static void update_state (NMConnectivity *self, NMConnectivityState state) { NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); if (priv->state != state) { + nm_log_dbg (LOGD_CONCHECK, "Connectivity state changed from %s to %s", + state_name (priv->state), state_name (state)); priv->state = state; g_object_notify (G_OBJECT (self), NM_CONNECTIVITY_STATE); } @@ -93,6 +114,7 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_ self = NM_CONNECTIVITY (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); g_object_unref (self); priv = NM_CONNECTIVITY_GET_PRIVATE (self); + priv->pending_checks--; if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { nm_log_info (LOGD_CONCHECK, "Connectivity check for uri '%s' failed with '%s'.", @@ -124,10 +146,11 @@ nm_connectivity_check_cb (SoupSession *session, SoupMessage *msg, gpointer user_ } done: + update_state (self, new_state); + g_simple_async_result_set_op_res_gssize (simple, new_state); g_simple_async_result_complete (simple); - - update_state (self, new_state); + g_object_unref (simple); } static void @@ -136,11 +159,9 @@ run_check_complete (GObject *object, gpointer user_data) { NMConnectivity *self = NM_CONNECTIVITY (object); - NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); GError *error = NULL; nm_connectivity_check_finish (self, result, &error); - priv->running = FALSE; if (error) { nm_log_err (LOGD_CONCHECK, "Connectivity check failed: %s", error->message); g_error_free (error); @@ -151,14 +172,23 @@ static gboolean run_check (gpointer user_data) { NMConnectivity *self = NM_CONNECTIVITY (user_data); - NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); nm_connectivity_check_async (self, run_check_complete, NULL); - priv->running = TRUE; - nm_log_dbg (LOGD_CONCHECK, "Connectivity check with uri '%s' started.", priv->uri); - return TRUE; } + +static gboolean +idle_start_periodic_checks (gpointer user_data) +{ + NMConnectivity *self = user_data; + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + + priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); + if (!priv->pending_checks) + run_check (self); + + return FALSE; +} #endif void @@ -167,12 +197,14 @@ nm_connectivity_set_online (NMConnectivity *self, { #if WITH_CONCHECK NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); +#endif + nm_log_dbg (LOGD_CONCHECK, "nm_connectivity_set_online(%s)", online ? "TRUE" : "FALSE"); + +#if WITH_CONCHECK if (online && priv->uri && priv->interval) { if (!priv->check_id) - priv->check_id = g_timeout_add_seconds (priv->interval, run_check, self); - if (!priv->running) - run_check (self); + priv->check_id = g_timeout_add (0, idle_start_periodic_checks, self); return; } else if (priv->check_id) { @@ -201,6 +233,13 @@ nm_connectivity_check_async (NMConnectivity *self, g_return_if_fail (NM_IS_CONNECTIVITY (self)); priv = NM_CONNECTIVITY_GET_PRIVATE (self); +#if WITH_CONCHECK + if (callback == run_check_complete) + nm_log_dbg (LOGD_CONCHECK, "Periodic connectivity check started with uri '%s'.", priv->uri); + else +#endif + nm_log_dbg (LOGD_CONCHECK, "Connectivity check started with uri '%s'.", priv->uri); + simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, nm_connectivity_check_async); @@ -208,10 +247,13 @@ nm_connectivity_check_async (NMConnectivity *self, if (priv->uri && priv->interval) { msg = soup_message_new ("GET", priv->uri); soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); + /* Disable HTTP/1.1 keepalive; the connection should not persist */ + soup_message_headers_append (msg->request_headers, "Connection", "close"); soup_session_queue_message (priv->soup_session, msg, nm_connectivity_check_cb, simple); + priv->pending_checks++; return; } @@ -219,6 +261,7 @@ nm_connectivity_check_async (NMConnectivity *self, g_simple_async_result_set_op_res_gssize (simple, priv->state); g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); } NMConnectivityState @@ -291,6 +334,8 @@ set_property (GObject *object, guint property_id, g_free (priv->uri); priv->uri = NULL; } + if (uri) + soup_uri_free (uri); } #endif break; diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index 1cceb9b5..f57eeb8e 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -78,20 +78,33 @@ static void nm_dbus_manager_cleanup (NMDBusManager *self, gboolean dispose); static void start_reconnection_timeout (NMDBusManager *self); static void object_destroyed (NMDBusManager *self, gpointer object); +NM_DEFINE_SINGLETON_DESTRUCTOR (NMDBusManager); +NM_DEFINE_SINGLETON_WEAK_REF (NMDBusManager); + NMDBusManager * nm_dbus_manager_get (void) { - static NMDBusManager *singleton = NULL; - static gsize once = 0; - - if (g_once_init_enter (&once)) { - singleton = (NMDBusManager *) g_object_new (NM_TYPE_DBUS_MANAGER, NULL); - g_assert (singleton); - if (!nm_dbus_manager_init_bus (singleton)) - start_reconnection_timeout (singleton); - g_once_init_leave (&once, 1); + if (G_UNLIKELY (!singleton_instance)) { + nm_dbus_manager_setup (g_object_new (NM_TYPE_DBUS_MANAGER, NULL)); + if (!nm_dbus_manager_init_bus (singleton_instance)) + start_reconnection_timeout (singleton_instance); } - return singleton; + return singleton_instance; +} + +void +nm_dbus_manager_setup (NMDBusManager *instance) +{ + static char already_setup = FALSE; + + g_assert (NM_IS_DBUS_MANAGER (instance)); + g_assert (!already_setup); + g_assert (!singleton_instance); + + already_setup = TRUE; + singleton_instance = instance; + nm_singleton_instance_weak_ref_register (); + nm_log_dbg (LOGD_CORE, "create %s singleton (%p)", "NMDBusManager", singleton_instance); } /**************************************************************/ @@ -199,6 +212,7 @@ private_server_new (const char *path, nm_log_warn (LOGD_CORE, "(%s) failed to set up private socket %s: %s", tag, address, error.message); dbus_error_free (&error); + g_free (address); return NULL; } @@ -876,8 +890,11 @@ nm_dbus_manager_register_object (NMDBusManager *self, g_assert (G_IS_OBJECT (object)); - g_warn_if_fail (g_hash_table_lookup (priv->exported, object) == NULL); + if (g_hash_table_lookup (priv->exported, G_OBJECT (object))) + g_return_if_reached (); + g_hash_table_insert (priv->exported, G_OBJECT (object), g_strdup (path)); + g_object_weak_ref (G_OBJECT (object), (GWeakNotify) object_destroyed, self); if (priv->g_connection) dbus_g_connection_register_g_object (priv->g_connection, path, G_OBJECT (object)); @@ -890,8 +907,6 @@ nm_dbus_manager_register_object (NMDBusManager *self, G_OBJECT (object)); } } - - g_object_weak_ref (G_OBJECT (object), (GWeakNotify) object_destroyed, self); } void @@ -903,7 +918,10 @@ nm_dbus_manager_unregister_object (NMDBusManager *self, gpointer object) g_assert (G_IS_OBJECT (object)); - g_hash_table_remove (NM_DBUS_MANAGER_GET_PRIVATE (self)->exported, G_OBJECT (object)); + if (!g_hash_table_lookup (priv->exported, G_OBJECT (object))) + g_return_if_reached (); + + g_hash_table_remove (priv->exported, G_OBJECT (object)); g_object_weak_unref (G_OBJECT (object), (GWeakNotify) object_destroyed, self); if (priv->g_connection) diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h index cc7f3210..c87ee024 100644 --- a/src/nm-dbus-manager.h +++ b/src/nm-dbus-manager.h @@ -73,6 +73,7 @@ typedef struct { GType nm_dbus_manager_get_type (void); NMDBusManager * nm_dbus_manager_get (void); +void nm_dbus_manager_setup (NMDBusManager *instance); char * nm_dbus_manager_get_name_owner (NMDBusManager *self, const char *name, diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index 5cc1bcd2..153c1de6 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -44,30 +44,41 @@ typedef struct { gboolean has_v4_changes; gboolean has_v6_changes; } resync; + + /* During disposing, we unref the sources of all entries. This happens usually + * during shutdown, which might call the final deletion of the object. That + * again might cause calls back into NMDefaultRouteManager, which finds dangling + * pointers. + * Guard every publicly accessible function to return early if the instance + * is already disposing. */ + gboolean disposed; + + NMPlatform *platform; } NMDefaultRouteManagerPrivate; #define NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerPrivate)) G_DEFINE_TYPE (NMDefaultRouteManager, nm_default_route_manager, G_TYPE_OBJECT) -static NMDefaultRouteManager *_instance; +static NMDefaultRouteManager *singleton_instance; #define _LOG(level, addr_family, ...) \ G_STMT_START { \ - int __addr_family = (addr_family); \ - guint64 __domain = __addr_family == AF_INET ? LOGD_IP4 : LOGD_IP6; \ + const int __addr_family = (addr_family); \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = __addr_family == AF_INET ? LOGD_IP4 : (__addr_family == AF_INET6 ? LOGD_IP6 : LOGD_IP); \ \ - if (nm_logging_enabled ((level), (__domain))) { \ + if (nm_logging_enabled (__level, __domain)) { \ char __ch = __addr_family == AF_INET ? '4' : (__addr_family == AF_INET6 ? '6' : '-'); \ char __prefix[30] = "default-route"; \ \ - if ((self) != _instance) \ + if ((self) != singleton_instance) \ g_snprintf (__prefix, sizeof (__prefix), "default-route%c[%p]", __ch, (self)); \ else \ __prefix[STRLEN ("default-route")] = __ch; \ - nm_log ((level), (__domain), \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + _nm_log (__level, __domain, 0, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } \ } G_STMT_END @@ -131,22 +142,16 @@ typedef struct { } Entry; typedef struct { - int addr_family; + const NMPlatformVTableRoute *vt; GPtrArray *(*get_entries) (NMDefaultRouteManagerPrivate *priv); - const char *(*platform_route_to_string) (const NMPlatformIPRoute *route); - GArray *(*platform_route_get_all) (int ifindex, NMPlatformGetRouteMode mode); - gboolean (*platform_route_delete_default) (int ifindex, guint32 metric); - guint32 (*route_metric_normalize) (guint32 metric); } VTableIP; static const VTableIP vtable_ip4, vtable_ip6; -#define VTABLE_IS_IP4 (vtable->addr_family == AF_INET) - static NMPlatformIPRoute * _vt_route_index (const VTableIP *vtable, GArray *routes, guint index) { - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, index); else return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, index); @@ -160,7 +165,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry route.rx.metric = entry->effective_metric; - if (VTABLE_IS_IP4) { + if (vtable->vt->is_ip4) { for (i = 0; i < routes->len; i++) { NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i); @@ -250,7 +255,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g if (!entry) return FALSE; - if (VTABLE_IS_IP4) { + if (vtable->vt->is_ip4) { success = nm_platform_ip4_route_add (entry->route.rx.ifindex, entry->route.rx.source, 0, @@ -269,8 +274,8 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g entry->route.rx.mss); } if (!success) { - _LOGW (vtable->addr_family, "failed to add default route %s with effective metric %u", - vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric); + _LOGW (vtable->vt->addr_family, "failed to add default route %s with effective metric %u", + vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric); } return TRUE; } @@ -285,7 +290,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self, gboolean changed = FALSE; /* prune all other default routes from this device. */ - routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + routes = vtable->vt->route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); for (i = 0; i < routes->len; i++) { const NMPlatformIPRoute *route; @@ -317,7 +322,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self, */ if ( !entry && (has_ifindex_synced || ifindex_to_flush == route->ifindex)) { - vtable->platform_route_delete_default (route->ifindex, route->metric); + vtable->vt->route_delete_default (route->ifindex, route->metric); changed = TRUE; } } @@ -401,7 +406,7 @@ _get_assumed_interface_metrics (const VTableIP *vtable, NMDefaultRouteManager *s } if (!ifindex_has_synced_entry) - g_hash_table_add (result, GUINT_TO_POINTER (vtable->route_metric_normalize (route->metric))); + g_hash_table_add (result, GUINT_TO_POINTER (vtable->vt->metric_normalize (route->metric))); } return result; @@ -437,7 +442,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c priv->resync.guard++; if (!external_change) { - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) priv->resync.has_v4_changes = FALSE; else priv->resync.has_v6_changes = FALSE; @@ -447,7 +452,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c entries = vtable->get_entries (priv); - routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + routes = vtable->vt->route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); assumed_metrics = _get_assumed_interface_metrics (vtable, self, routes); @@ -517,24 +522,24 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c * or none. Hence, we only have to remember what is going to change. */ g_array_append_val (changed_metrics, expected_metric); if (old_entry) { - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": update %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), - vtable->platform_route_to_string (&entry->route.rx), (guint) old_entry->effective_metric, + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": update %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->vt->route_to_string (&entry->route), (guint) old_entry->effective_metric, (guint) expected_metric); } else { - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": add %s (%u)", LOG_ENTRY_ARGS (i, entry), - vtable->platform_route_to_string (&entry->route.rx), (guint) expected_metric); + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": add %s (%u)", LOG_ENTRY_ARGS (i, entry), + vtable->vt->route_to_string (&entry->route), (guint) expected_metric); } } else if (entry->effective_metric != expected_metric) { g_array_append_val (changed_metrics, entry->effective_metric); g_array_append_val (changed_metrics, expected_metric); - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": resync metric %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), - vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric, + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": resync metric %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric, (guint) expected_metric); } else { if (!_vt_routes_has_entry (vtable, routes, entry)) { g_array_append_val (changed_metrics, entry->effective_metric); - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": readd route %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), - vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric, + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": readd route %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric, (guint) entry->effective_metric); } } @@ -598,10 +603,10 @@ _entry_at_idx_update (const VTableIP *vtable, NMDefaultRouteManager *self, guint if (!entry->synced && !entry->never_default) entry->effective_metric = entry->route.rx.metric; - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": %s %s", + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": %s %s", LOG_ENTRY_ARGS (entry_idx, entry), old_entry ? "update" : "add", - vtable->platform_route_to_string (&entry->route.rx)); + vtable->vt->route_to_string (&entry->route)); g_ptr_array_sort_with_data (entries, _sort_entries_cmp, NULL); @@ -621,8 +626,8 @@ _entry_at_idx_remove (const VTableIP *vtable, NMDefaultRouteManager *self, guint entry = g_ptr_array_index (entries, entry_idx); - _LOGD (vtable->addr_family, LOG_ENTRY_FMT": remove %s (%u)", LOG_ENTRY_ARGS (entry_idx, entry), - vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric); + _LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": remove %s (%u)", LOG_ENTRY_ARGS (entry_idx, entry), + vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric); /* Remove the entry from the list (but don't free it yet) */ g_ptr_array_index (entries, entry_idx) = NULL; @@ -651,6 +656,11 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, gboolean synced = FALSE; g_return_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self)); + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + if (priv->disposed) + return; + if (NM_IS_DEVICE (source)) device = source; else if (NM_IS_VPN_CONNECTION (source)) @@ -671,15 +681,13 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, } } - priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); - entries = vtable->get_entries (priv); entry = _entry_find_by_source (entries, source, &entry_idx); if ( entry && entry->route.rx.ifindex != ip_ifindex) { /* Strange... the ifindex changed... Remove the device and start again. */ - _LOGD (vtable->addr_family, "ifindex of "LOG_ENTRY_FMT" changed: %d -> %d", + _LOGD (vtable->vt->addr_family, "ifindex of "LOG_ENTRY_FMT" changed: %d -> %d", LOG_ENTRY_ARGS (entry_idx, entry), entry->route.rx.ifindex, ip_ifindex); @@ -696,7 +704,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, if (device) { gboolean is_assumed; - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) default_route = (const NMPlatformIPRoute *) nm_device_get_ip4_default_route (device, &is_assumed); else default_route = (const NMPlatformIPRoute *) nm_device_get_ip6_default_route (device, &is_assumed); @@ -724,7 +732,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, && nm_vpn_connection_get_vpn_state (vpn) == NM_VPN_CONNECTION_STATE_ACTIVATED) { memset (&rt, 0, sizeof (rt)); - if (VTABLE_IS_IP4) { + if (vtable->vt->is_ip4) { NMIP4Config *vpn_config; vpn_config = nm_vpn_connection_get_ip4_config (vpn); @@ -766,13 +774,13 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, entry = g_slice_new0 (Entry); entry->source.object = g_object_ref (source); - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) entry->route.r4 = *((const NMPlatformIP4Route *) default_route); else entry->route.r6 = *((const NMPlatformIP6Route *) default_route); /* only use normalized metrics */ - entry->route.rx.metric = vtable->route_metric_normalize (entry->route.rx.metric); + entry->route.rx.metric = vtable->vt->metric_normalize (entry->route.rx.metric); entry->route.rx.ifindex = ip_ifindex; entry->never_default = never_default; entry->effective_metric = entry->route.rx.metric; @@ -785,12 +793,12 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, Entry old_entry, new_entry; new_entry = *entry; - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) new_entry.route.r4 = *((const NMPlatformIP4Route *) default_route); else new_entry.route.r6 = *((const NMPlatformIP6Route *) default_route); /* only use normalized metrics */ - new_entry.route.rx.metric = vtable->route_metric_normalize (new_entry.route.rx.metric); + new_entry.route.rx.metric = vtable->vt->metric_normalize (new_entry.route.rx.metric); new_entry.route.rx.ifindex = ip_ifindex; new_entry.never_default = never_default; new_entry.synced = synced; @@ -830,14 +838,14 @@ _ipx_connection_has_default_route (const VTableIP *vtable, NMDefaultRouteManager g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) s_ip = nm_connection_get_setting_ip4_config (connection); else s_ip = nm_connection_get_setting_ip6_config (connection); if (!s_ip || nm_setting_ip_config_get_never_default (s_ip)) return FALSE; - if (VTABLE_IS_IP4) { + if (vtable->vt->is_ip4) { method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); if ( !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) @@ -881,10 +889,13 @@ _ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const return NULL; priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + if (priv->disposed) + return NULL; entries = vtable->get_entries (priv); for (i = 0; i < entries->len; i++) { Entry *entry = g_ptr_array_index (entries, i); + NMDeviceState state; if (!NM_IS_DEVICE (entry->source.pointer)) continue; @@ -892,8 +903,22 @@ _ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const if (entry->never_default) continue; - if (g_slist_find ((GSList *) devices, entry->source.device)) + state = nm_device_get_state (entry->source.device); + if ( state <= NM_DEVICE_STATE_DISCONNECTED + || state >= NM_DEVICE_STATE_DEACTIVATING) { + /* FIXME: we also track unmanaged devices with assumed default routes. + * Skip them, they are (currently) no candidates for best-device. + * + * Later we also want to properly assume connections for unmanaged devices. + * + * Also, we don't want to have DEACTIVATING devices returned as best_device(). */ + continue; + } + + if (g_slist_find ((GSList *) devices, entry->source.device)) { + g_return_val_if_fail (nm_device_get_act_request (entry->source.pointer), entry->source.pointer); return entry->source.pointer; + } } return NULL; } @@ -920,6 +945,8 @@ _ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager * g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + if (priv->disposed) + return NULL; best_activated_device = _ipx_get_best_device (vtable, self, devices); @@ -948,7 +975,7 @@ _ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager * prio = nm_device_get_ip4_route_metric (device); } - prio = vtable->route_metric_normalize (prio); + prio = vtable->vt->metric_normalize (prio); if ( !best_device || prio < best_prio @@ -1013,6 +1040,8 @@ _ipx_get_best_config (const VTableIP *vtable, *out_vpn = NULL; priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + if (priv->disposed) + return NULL; g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); @@ -1028,7 +1057,7 @@ _ipx_get_best_config (const VTableIP *vtable, if (entry->never_default && !ignore_never_default) continue; - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) config_result = nm_vpn_connection_get_ip4_config (vpn); else config_result = nm_vpn_connection_get_ip6_config (vpn); @@ -1043,11 +1072,25 @@ _ipx_get_best_config (const VTableIP *vtable, } else { NMDevice *device = entry->source.device; NMActRequest *req; + NMDeviceState state; if (entry->never_default) continue; - if (VTABLE_IS_IP4) + state = nm_device_get_state (device); + if ( state <= NM_DEVICE_STATE_DISCONNECTED + || state >= NM_DEVICE_STATE_DEACTIVATING) { + /* FIXME: the device has a default route, but we ignore it due to + * unexpected state. That happens for example for unmanaged devices. + * + * In the future, we want unmanaged devices also assume a connection + * if they are activated externally. + * + * Also, we don't want to have DEACTIVATING devices returned as best_config(). */ + continue; + } + + if (vtable->vt->is_ip4) config_result = nm_device_get_ip4_config (device); else config_result = nm_device_get_ip6_config (device); @@ -1116,40 +1159,14 @@ _v6_get_entries (NMDefaultRouteManagerPrivate *priv) return priv->entries_ip6; } -static gboolean -_v4_platform_route_delete_default (int ifindex, guint32 metric) -{ - return nm_platform_ip4_route_delete (ifindex, 0, 0, metric); -} - -static gboolean -_v6_platform_route_delete_default (int ifindex, guint32 metric) -{ - return nm_platform_ip6_route_delete (ifindex, in6addr_any, 0, metric); -} - -static guint32 -_v4_route_metric_normalize (guint32 metric) -{ - return metric; -} - static const VTableIP vtable_ip4 = { - .addr_family = AF_INET, + .vt = &nm_platform_vtable_route_v4, .get_entries = _v4_get_entries, - .platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip4_route_to_string, - .platform_route_get_all = nm_platform_ip4_route_get_all, - .platform_route_delete_default = _v4_platform_route_delete_default, - .route_metric_normalize = _v4_route_metric_normalize, }; static const VTableIP vtable_ip6 = { - .addr_family = AF_INET6, + .vt = &nm_platform_vtable_route_v6, .get_entries = _v6_get_entries, - .platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip6_route_to_string, - .platform_route_get_all = nm_platform_ip6_route_get_all, - .platform_route_delete_default = _v6_platform_route_delete_default, - .route_metric_normalize = nm_utils_ip6_route_metric_normalize, }; /***********************************************************************************/ @@ -1157,11 +1174,11 @@ static const VTableIP vtable_ip6 = { NMDefaultRouteManager * nm_default_route_manager_get () { - if (G_UNLIKELY (!_instance)) { - _instance = NM_DEFAULT_ROUTE_MANAGER (g_object_new (NM_TYPE_DEFAULT_ROUTE_MANAGER, NULL)); - g_object_add_weak_pointer (G_OBJECT (_instance), (gpointer *) &_instance); + if (G_UNLIKELY (!singleton_instance)) { + singleton_instance = NM_DEFAULT_ROUTE_MANAGER (g_object_new (NM_TYPE_DEFAULT_ROUTE_MANAGER, NULL)); + g_object_add_weak_pointer (G_OBJECT (singleton_instance), (gpointer *) &singleton_instance); } - return _instance; + return singleton_instance; } /***********************************************************************************/ @@ -1260,7 +1277,7 @@ _platform_ipx_route_changed_cb (const VTableIP *vtable, return; } - if (VTABLE_IS_IP4) + if (vtable->vt->is_ip4) priv->resync.has_v4_changes = TRUE; else priv->resync.has_v6_changes = TRUE; @@ -1318,16 +1335,15 @@ static void nm_default_route_manager_init (NMDefaultRouteManager *self) { NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); - NMPlatform *platform; priv->entries_ip4 = g_ptr_array_new_full (0, (GDestroyNotify) _entry_free); priv->entries_ip6 = g_ptr_array_new_full (0, (GDestroyNotify) _entry_free); - platform = nm_platform_get (); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_platform_ip4_address_changed_cb), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_platform_ip6_address_changed_cb), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_platform_ip4_route_changed_cb), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_platform_ip6_route_changed_cb), self); + priv->platform = g_object_ref (nm_platform_get ()); + g_signal_connect (priv->platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_platform_ip4_address_changed_cb), self); + g_signal_connect (priv->platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_platform_ip6_address_changed_cb), self); + g_signal_connect (priv->platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_platform_ip4_route_changed_cb), self); + g_signal_connect (priv->platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_platform_ip6_route_changed_cb), self); } static void @@ -1336,6 +1352,22 @@ dispose (GObject *object) NMDefaultRouteManager *self = NM_DEFAULT_ROUTE_MANAGER (object); NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + priv->disposed = TRUE; + + if (priv->platform) { + g_signal_handlers_disconnect_by_data (priv->platform, self); + g_clear_object (&priv->platform); + } + + _resync_idle_cancel (self); + + /* g_ptr_array_free() invokes the free function for all entries without actually + * removing them and having dangling pointers in the process. _entry_free() + * will unref the source, which might cause the destruction of the object, which + * might trigger calling into @self again. This is guarded by priv->dispose. + * If you remove priv->dispose, you must refactor the lines below to remove enties + * one-by-one. + */ if (priv->entries_ip4) { g_ptr_array_free (priv->entries_ip4, TRUE); priv->entries_ip4 = NULL; @@ -1345,10 +1377,6 @@ dispose (GObject *object) priv->entries_ip6 = NULL; } - _resync_idle_cancel (self); - - g_signal_handlers_disconnect_by_data (nm_platform_get (), self); - G_OBJECT_CLASS (nm_default_route_manager_parent_class)->dispose (object); } diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index ae451768..4e200266 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -37,6 +37,7 @@ #include "nm-dhcp6-config.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-settings-connection.h" #define CALL_TIMEOUT (1000 * 60 * 10) /* 10 minutes for all scripts */ @@ -474,6 +475,7 @@ _dispatcher_call (DispatcherAction action, if (connection) { GVariant *connection_dict; + const char *filename; connection_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); connection_hash = nm_utils_connection_dict_to_hash (connection_dict); @@ -483,6 +485,12 @@ _dispatcher_call (DispatcherAction action, value_hash_add_object_path (connection_props, NMD_CONNECTION_PROPS_PATH, nm_connection_get_path (connection)); + filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); + if (filename) { + value_hash_add_str (connection_props, + NMD_CONNECTION_PROPS_FILENAME, + filename); + } } else { connection_hash = value_hash_create (); connection_props = value_hash_create (); diff --git a/src/nm-enum-types.c b/src/nm-enum-types.c index ee1df59f..c3f15f38 100644 --- a/src/nm-enum-types.c +++ b/src/nm-enum-types.c @@ -45,6 +45,7 @@ #include "nm-fake-rdisc.h" #include "nm-lndp-rdisc.h" #include "nm-rdisc.h" +#include "nm-rdisc-private.h" #include "nm-ppp-manager.h" #include "nm-ppp-status.h" #include "nm-agent-manager.h" @@ -96,8 +97,7 @@ #include "nm-sleep-monitor.h" #include "nm-types.h" #include "NetworkManagerUtils.h" -#include "wifi-utils-wext.h" -#include "nm-device-wimax.h" +#include "wifi-utils-wext.h" GType nm_vlan_error_get_type (void) @@ -126,7 +126,7 @@ nm_unmanaged_flags_get_type (void) if (g_once_init_enter (&g_define_type_id__volatile)) { - static const GEnumValue values[] = { + static const GFlagsValue values[] = { { NM_UNMANAGED_NONE, "NM_UNMANAGED_NONE", "nm-unmanaged-none" }, { NM_UNMANAGED_DEFAULT, "NM_UNMANAGED_DEFAULT", "nm-unmanaged-default" }, { NM_UNMANAGED_INTERNAL, "NM_UNMANAGED_INTERNAL", "nm-unmanaged-internal" }, @@ -135,10 +135,11 @@ nm_unmanaged_flags_get_type (void) { NM_UNMANAGED_EXTERNAL_DOWN, "NM_UNMANAGED_EXTERNAL_DOWN", "nm-unmanaged-external-down" }, { __NM_UNMANAGED_LAST, "__NM_UNMANAGED_LAST", "--nm-unmanaged-last" }, { NM_UNMANAGED_LAST, "NM_UNMANAGED_LAST", "nm-unmanaged-last" }, + { NM_UNMANAGED_ALL, "NM_UNMANAGED_ALL", "nm-unmanaged-all" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMUnmanagedFlags"), values); + g_flags_register_static (g_intern_static_string ("NMUnmanagedFlags"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -260,10 +261,11 @@ nm_platform_reason_get_type (void) if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_PLATFORM_REASON_NONE, "NM_PLATFORM_REASON_NONE", "none" }, - { NM_PLATFORM_REASON_INTERNAL, "NM_PLATFORM_REASON_INTERNAL", "internal" }, - { NM_PLATFORM_REASON_EXTERNAL, "NM_PLATFORM_REASON_EXTERNAL", "external" }, - { NM_PLATFORM_REASON_CACHE_CHECK, "NM_PLATFORM_REASON_CACHE_CHECK", "cache-check" }, + { NM_PLATFORM_REASON_NONE, "NM_PLATFORM_REASON_NONE", "nm-platform-reason-none" }, + { NM_PLATFORM_REASON_INTERNAL, "NM_PLATFORM_REASON_INTERNAL", "nm-platform-reason-internal" }, + { NM_PLATFORM_REASON_EXTERNAL, "NM_PLATFORM_REASON_EXTERNAL", "nm-platform-reason-external" }, + { NM_PLATFORM_REASON_CACHE_CHECK, "NM_PLATFORM_REASON_CACHE_CHECK", "nm-platform-reason-cache-check" }, + { _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL, "_NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL", "-nm-platform-reason-cache-check-internal" }, { 0, NULL, NULL } }; GType g_define_type_id = diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 9d5cdc05..97e1708e 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -34,6 +34,10 @@ #include <sys/stat.h> #include <signal.h> +/* Cannot include <net/if.h> due to conflict with <linux/if.h>. + * Forward declare if_nametoindex. */ +extern unsigned int if_nametoindex (const char *__ifname); + #include "gsystem-local-alloc.h" #include "NetworkManagerUtils.h" #include "nm-linux-platform.h" @@ -51,13 +55,32 @@ #define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid" static GMainLoop *main_loop = NULL; -static char *ifname = NULL; static int ifindex = -1; -static gboolean slaac_required = FALSE; -static gboolean dhcp4_required = FALSE; -static int tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; -static guint32 priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4; -static guint32 priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6; + +static struct { + gboolean slaac; + gboolean show_version; + gboolean become_daemon; + gboolean debug; + gboolean g_fatal_warnings; + gboolean slaac_required; + gboolean dhcp4_required; + int tempaddr; + char *ifname; + char *uuid; + char *dhcp4_address; + char *dhcp4_clientid; + char *dhcp4_hostname; + char *iid_str; + char *opt_log_level; + char *opt_log_domains; + guint32 priority_v4; + guint32 priority_v6; +} global_opt = { + .tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + .priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4, + .priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, +}; static void dhcp4_state_changed (NMDhcpClient *client, @@ -71,7 +94,7 @@ dhcp4_state_changed (NMDhcpClient *client, g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config)); - nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", ifname, state); + nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", global_opt.ifname, state); switch (state) { case NM_DHCP_STATE_BOUND: @@ -81,23 +104,22 @@ dhcp4_state_changed (NMDhcpClient *client, nm_ip4_config_subtract (existing, last_config); nm_ip4_config_merge (existing, ip4_config); - if (!nm_ip4_config_commit (existing, ifindex, priority_v4)) - nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", ifname); + if (!nm_ip4_config_commit (existing, ifindex, global_opt.priority_v4)) + nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", global_opt.ifname); - if (last_config) { + if (last_config) g_object_unref (last_config); - last_config = nm_ip4_config_new (); - nm_ip4_config_replace (last_config, ip4_config, NULL); - } + last_config = nm_ip4_config_new (); + nm_ip4_config_replace (last_config, ip4_config, NULL); break; case NM_DHCP_STATE_TIMEOUT: case NM_DHCP_STATE_DONE: case NM_DHCP_STATE_FAIL: - if (dhcp4_required) { - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", ifname); + if (global_opt.dhcp4_required) { + nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", global_opt.ifname); g_main_loop_quit (main_loop); } else - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed", ifname); + nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed", global_opt.ifname); break; default: break; @@ -128,8 +150,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da if (system_support) ifa_flags = IFA_F_NOPREFIXROUTE; - if (tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR - || tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) + if (global_opt.tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR + || global_opt.tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) { /* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */ ifa_flags |= IFA_F_MANAGETEMPADDR; @@ -193,7 +215,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da route.plen = discovered_route->plen; route.gateway = discovered_route->gateway; route.source = NM_IP_CONFIG_SOURCE_RDISC; - route.metric = priority_v6; + route.metric = global_opt.priority_v6; nm_ip6_config_add_route (ip6_config, &route); } @@ -204,45 +226,38 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da /* Unsupported until systemd DHCPv6 is ready */ } - /* hop_limit == 0 is a special value "unspecified", so do not touch - * in this case */ - if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) { - char val[16]; - - g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "hop_limit"), val); - } + if (changed & NM_RDISC_CONFIG_HOP_LIMIT) + nm_platform_sysctl_set_ip6_hop_limit_safe (global_opt.ifname, rdisc->hop_limit); if (changed & NM_RDISC_CONFIG_MTU) { char val[16]; g_snprintf (val, sizeof (val), "%d", rdisc->mtu); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "mtu"), val); + nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val); } - existing = nm_ip6_config_capture (ifindex, FALSE, tempaddr); + existing = nm_ip6_config_capture (ifindex, FALSE, global_opt.tempaddr); if (last_config) nm_ip6_config_subtract (existing, last_config); nm_ip6_config_merge (existing, ip6_config); if (!nm_ip6_config_commit (existing, ifindex)) - nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", ifname); + nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", global_opt.ifname); - if (last_config) { + if (last_config) g_object_unref (last_config); - last_config = nm_ip6_config_new (); - nm_ip6_config_replace (last_config, ip6_config, NULL); - } + last_config = nm_ip6_config_new (); + nm_ip6_config_replace (last_config, ip6_config, NULL); } static void rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data) { - if (slaac_required) { - nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", ifname); + if (global_opt.slaac_required) { + nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", global_opt.ifname); g_main_loop_quit (main_loop); } else - nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed", ifname); + nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed", global_opt.ifname); } static gboolean @@ -268,78 +283,108 @@ setup_signals (gboolean *quit_early_ptr) g_unix_signal_add (SIGTERM, quit_handler, quit_early_ptr); } -int -main (int argc, char *argv[]) +static void +do_early_setup (int *argc, char **argv[]) { - char *opt_log_level = NULL; - char *opt_log_domains = NULL; - gboolean debug = FALSE, g_fatal_warnings = FALSE, become_daemon = FALSE; - gboolean show_version = FALSE, slaac = FALSE; - char *bad_domains = NULL, *dhcp4_hostname = NULL, *uuid = NULL; - char *iid_str = NULL, *dhcp4_clientid = NULL, *dhcp4_address = NULL; - gs_unref_object NMDhcpManager *dhcp_mgr = NULL; - GError *error = NULL; - gboolean wrote_pidfile = FALSE; - gs_free char *pidfile = NULL; - gboolean quit_early = FALSE; - gs_unref_object NMDhcpClient *dhcp4_client = NULL; - gs_unref_object NMRDisc *rdisc = NULL; - GByteArray *hwaddr = NULL; - size_t hwaddr_len = 0; - gconstpointer tmp; - gs_free NMUtilsIPv6IfaceId *iid = NULL; gint64 priority64_v4 = -1; gint64 priority64_v6 = -1; - GOptionEntry options[] = { /* Interface/IP config */ - { "ifname", 'i', 0, G_OPTION_ARG_STRING, &ifname, N_("The interface to manage"), N_("eth0") }, - { "uuid", 'u', 0, G_OPTION_ARG_STRING, &uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") }, - { "slaac", 's', 0, G_OPTION_ARG_NONE, &slaac, N_("Whether to manage IPv6 SLAAC"), NULL }, - { "slaac-required", '6', 0, G_OPTION_ARG_NONE, &slaac_required, N_("Whether SLAAC must be successful"), NULL }, - { "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &tempaddr, N_("Use an IPv6 temporary privacy address"), NULL }, - { "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &dhcp4_address, N_("Current DHCPv4 address"), NULL }, - { "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL }, - { "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL }, - { "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") }, + { "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), N_("eth0") }, + { "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") }, + { "slaac", 's', 0, G_OPTION_ARG_NONE, &global_opt.slaac, N_("Whether to manage IPv6 SLAAC"), NULL }, + { "slaac-required", '6', 0, G_OPTION_ARG_NONE, &global_opt.slaac_required, N_("Whether SLAAC must be successful"), NULL }, + { "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &global_opt.tempaddr, N_("Use an IPv6 temporary privacy address"), NULL }, + { "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_address, N_("Current DHCPv4 address"), NULL }, + { "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &global_opt.dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL }, + { "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL }, + { "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") }, { "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") }, { "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") }, - { "iid", 'e', 0, G_OPTION_ARG_STRING, &iid_str, N_("Hex-encoded Interface Identifier"), N_("") }, + { "iid", 'e', 0, G_OPTION_ARG_STRING, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), "" }, /* Logging/debugging */ - { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL }, - { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL }, - { "debug", 'b', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL }, - { "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" }, - { "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains, + { "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL }, + { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL }, + { "debug", 'b', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), NULL }, + { "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" }, + { "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains, N_("Log domains separated by ',': any combination of [%s]"), "PLATFORM,RFKILL,WIFI" }, - { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL }, + { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL }, {NULL} }; - setpgid (getpid (), getpid ()); - if (!nm_main_utils_early_setup ("nm-iface-helper", - &argv, - &argc, + argc, + argv, options, NULL, _("nm-iface-helper is a small, standalone process that manages a single network interface."))) exit (1); - if (show_version) { + if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32) + global_opt.priority_v4 = (guint32) priority64_v4; + if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32) + global_opt.priority_v6 = (guint32) priority64_v6; +} + +int +main (int argc, char *argv[]) +{ + char *bad_domains = NULL; + gs_unref_object NMDhcpManager *dhcp_mgr = NULL; + GError *error = NULL; + gboolean wrote_pidfile = FALSE; + gs_free char *pidfile = NULL; + gboolean quit_early = FALSE; + gs_unref_object NMDhcpClient *dhcp4_client = NULL; + gs_unref_object NMRDisc *rdisc = NULL; + GByteArray *hwaddr = NULL; + size_t hwaddr_len = 0; + gconstpointer tmp; + gs_free NMUtilsIPv6IfaceId *iid = NULL; + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + setpgid (getpid (), getpid ()); + + do_early_setup (&argc, &argv); + + if (global_opt.g_fatal_warnings) { + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); + } + + if (global_opt.show_version) { fprintf (stdout, NM_DIST_VERSION "\n"); exit (0); } - if (!ifname || !uuid) { + nm_main_utils_ensure_root (); + + if (!global_opt.ifname || !global_opt.uuid) { fprintf (stderr, _("An interface name and UUID are required\n")); exit (1); } - if (!nm_logging_setup (opt_log_level, - opt_log_domains, + ifindex = if_nametoindex (global_opt.ifname); + if (ifindex <= 0) { + fprintf (stderr, _("Failed to find interface index for %s (%s)\n"), global_opt.ifname, strerror (errno)); + exit (1); + } + pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex); + nm_main_utils_ensure_not_running_pidfile (pidfile); + + nm_main_utils_ensure_rundir (); + + if (!nm_logging_setup (global_opt.opt_log_level, + global_opt.opt_log_domains, &bad_domains, &error)) { fprintf (stderr, @@ -353,14 +398,7 @@ main (int argc, char *argv[]) g_clear_pointer (&bad_domains, g_free); } - pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex); - g_assert (pidfile); - - /* check pid file */ - if (nm_main_utils_check_pidfile (pidfile, "nm-iface-helper")) - exit (1); - - if (become_daemon && !debug) { + if (global_opt.become_daemon && !global_opt.debug) { if (daemon (0, 0) < 0) { int saved_errno; @@ -378,74 +416,50 @@ main (int argc, char *argv[]) main_loop = g_main_loop_new (NULL, FALSE); setup_signals (&quit_early); - if (g_fatal_warnings) { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - nm_logging_syslog_openlog (debug); - -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + nm_logging_syslog_openlog (global_opt.debug); nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting..."); /* Set up platform interaction layer */ nm_linux_platform_setup (); - ifindex = nm_platform_link_get_ifindex (ifname); - if (ifindex <= 0) { - fprintf (stderr, _("Failed to find interface index for %s\n"), ifname); - exit (1); - } - tmp = nm_platform_link_get_address (ifindex, &hwaddr_len); if (tmp) { hwaddr = g_byte_array_sized_new (hwaddr_len); g_byte_array_append (hwaddr, tmp, hwaddr_len); } - if (iid_str) { + if (global_opt.iid_str) { GBytes *bytes; gsize ignored = 0; - bytes = nm_utils_hexstr2bin (iid_str); + bytes = nm_utils_hexstr2bin (global_opt.iid_str); if (!bytes || g_bytes_get_size (bytes) != sizeof (*iid)) { - fprintf (stderr, _("(%s): Invalid IID %s\n"), ifname, iid_str); + fprintf (stderr, _("(%s): Invalid IID %s\n"), global_opt.ifname, global_opt.iid_str); exit (1); } iid = g_bytes_unref_to_data (bytes, &ignored); } - if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32) - priority_v4 = (guint32) priority64_v4; - - if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32) - priority_v6 = (guint32) priority64_v6; - - if (dhcp4_address) { - nm_platform_sysctl_set (nm_utils_ip4_property_path (ifname, "promote_secondaries"), "1"); + if (global_opt.dhcp4_address) { + nm_platform_sysctl_set (nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1"); /* Initialize DHCP manager */ dhcp_mgr = nm_dhcp_manager_get (); g_assert (dhcp_mgr != NULL); dhcp4_client = nm_dhcp_manager_start_ip4 (dhcp_mgr, - ifname, + global_opt.ifname, ifindex, hwaddr, - uuid, - priority_v4, - !!dhcp4_hostname, - dhcp4_hostname, - dhcp4_clientid, + global_opt.uuid, + global_opt.priority_v4, + !!global_opt.dhcp4_hostname, + global_opt.dhcp4_hostname, + global_opt.dhcp4_clientid, 45, NULL, - dhcp4_address); + global_opt.dhcp4_address); g_assert (dhcp4_client); g_signal_connect (dhcp4_client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, @@ -453,19 +467,19 @@ main (int argc, char *argv[]) NULL); } - if (slaac) { + if (global_opt.slaac) { nm_platform_link_set_user_ipv6ll_enabled (ifindex, TRUE); - rdisc = nm_lndp_rdisc_new (ifindex, ifname); + rdisc = nm_lndp_rdisc_new (ifindex, global_opt.ifname); g_assert (rdisc); if (iid) nm_rdisc_set_iid (rdisc, *iid); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra"), "1"); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_defrtr"), "0"); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_pinfo"), "0"); - nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_rtr_pref"), "0"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra"), "1"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr"), "0"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo"), "0"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref"), "0"); g_signal_connect (rdisc, NM_RDISC_CONFIG_CHANGED, diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index fd466780..db2ef158 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1721,6 +1721,8 @@ finalize (GObject *object) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); + g_free (priv->path); + g_array_unref (priv->addresses); g_array_unref (priv->routes); g_array_unref (priv->nameservers); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index db64e726..cf8d74be 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -375,7 +375,7 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex) g_return_val_if_fail (config != NULL, FALSE); /* Addresses */ - nm_platform_ip6_address_sync (ifindex, priv->addresses); + nm_platform_ip6_address_sync (ifindex, priv->addresses, TRUE); /* Routes */ { @@ -1584,6 +1584,8 @@ finalize (GObject *object) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); + g_free (priv->path); + g_array_unref (priv->addresses); g_array_unref (priv->routes); g_array_unref (priv->nameservers); diff --git a/src/nm-logging.c b/src/nm-logging.c index f1291fa7..fa770344 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -357,13 +357,14 @@ nm_logging_enabled (NMLogLevel level, NMLogDomain domain) } void -_nm_log (const char *file, - guint line, - const char *func, - NMLogLevel level, - NMLogDomain domain, - const char *fmt, - ...) +_nm_log_impl (const char *file, + guint line, + const char *func, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *fmt, + ...) { va_list args; char *msg; @@ -379,6 +380,10 @@ _nm_log (const char *file, if (!(logging[level] & domain)) return; + /* Make sure that %m maps to the specified error */ + if (error != 0) + errno = error; + va_start (args, fmt); msg = g_strdup_vprintf (fmt, args); va_end (args); diff --git a/src/nm-logging.h b/src/nm-logging.h index 4ab2db3a..00d429b0 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -100,12 +100,20 @@ typedef enum { /*< skip >*/ #define nm_log_dbg(domain, ...) nm_log (LOGL_DEBUG, (domain), __VA_ARGS__) #define nm_log_trace(domain, ...) nm_log (LOGL_TRACE, (domain), __VA_ARGS__) +/* A wrapper for the _nm_log_impl() function that adds call site information. + * Contrary to nm_log(), it unconditionally calls the function without + * checking whether logging for the given level and domain is enabled. */ +#define _nm_log(level, domain, error, ...) \ + G_STMT_START { \ + _nm_log_impl (__FILE__, __LINE__, G_STRFUNC, (level), (domain), (error), ""__VA_ARGS__); \ + } G_STMT_END + /* nm_log() only evaluates it's argument list after checking * whether logging for the given level/domain is enabled. */ #define nm_log(level, domain, ...) \ G_STMT_START { \ if (nm_logging_enabled ((level), (domain))) { \ - _nm_log (__FILE__, __LINE__, G_STRFUNC, (level), (domain), __VA_ARGS__); \ + _nm_log (level, domain, 0, __VA_ARGS__); \ } \ } G_STMT_END @@ -116,11 +124,13 @@ typedef enum { /*< skip >*/ /* log a message for an object (with providing a generic @self pointer) */ #define nm_log_ptr(level, domain, self, ...) \ G_STMT_START { \ + NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare") \ if ((level) <= LOGL_DEBUG) { \ _nm_log_ptr ((level), (domain), (self), __VA_ARGS__); \ } else { \ nm_log ((level), (domain), __VA_ARGS__); \ } \ + NM_PRAGMA_WARNING_REENABLE \ } G_STMT_END @@ -134,13 +144,14 @@ typedef enum { /*< skip >*/ nm_log_ptr ((level), (domain), (self), __VA_ARGS__) -void _nm_log (const char *file, - guint line, - const char *func, - NMLogLevel level, - NMLogDomain domain, - const char *fmt, - ...) __attribute__((__format__ (__printf__, 6, 7))); +void _nm_log_impl (const char *file, + guint line, + const char *func, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *fmt, + ...) __attribute__((__format__ (__printf__, 7, 8))); const char *nm_logging_level_to_string (void); const char *nm_logging_domains_to_string (void); diff --git a/src/nm-manager.c b/src/nm-manager.c index 7e81afa5..0fa88d1d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -578,7 +578,7 @@ checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data) } static NMState -find_best_device_state (NMManager *manager, gboolean *want_connectivity_check) +find_best_device_state (NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMState best_state = NM_STATE_DISCONNECTED; @@ -592,14 +592,10 @@ find_best_device_state (NMManager *manager, gboolean *want_connectivity_check) case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: if ( nm_active_connection_get_default (ac) || nm_active_connection_get_default6 (ac)) { - nm_connectivity_set_online (priv->connectivity, TRUE); - if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL) { - *want_connectivity_check = FALSE; + if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL) return NM_STATE_CONNECTED_GLOBAL; - } - best_state = NM_STATE_CONNECTING; - *want_connectivity_check = TRUE; + best_state = NM_STATE_CONNECTED_SITE; } else { if (best_state < NM_STATE_CONNECTING) best_state = NM_STATE_CONNECTED_LOCAL; @@ -630,7 +626,6 @@ nm_manager_update_state (NMManager *manager) { NMManagerPrivate *priv; NMState new_state = NM_STATE_DISCONNECTED; - gboolean want_connectivity_check = FALSE; g_return_if_fail (NM_IS_MANAGER (manager)); @@ -639,16 +634,16 @@ nm_manager_update_state (NMManager *manager) if (manager_sleeping (manager)) new_state = NM_STATE_ASLEEP; else - new_state = find_best_device_state (manager, &want_connectivity_check); + new_state = find_best_device_state (manager); + + nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL); - if (new_state == NM_STATE_CONNECTING && want_connectivity_check) { + if (new_state == NM_STATE_CONNECTED_SITE) { nm_connectivity_check_async (priv->connectivity, checked_connectivity, g_object_ref (manager)); - return; } - nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL); set_state (manager, new_state); } @@ -687,6 +682,11 @@ check_if_startup_complete (NMManager *self) if (!priv->startup) return; + if (!nm_settings_get_startup_complete (priv->settings)) { + nm_log_dbg (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings"); + return; + } + for (iter = priv->devices; iter; iter = iter->next) { NMDevice *dev = iter->data; @@ -722,6 +722,14 @@ device_has_pending_action_changed (NMDevice *device, } static void +settings_startup_complete_changed (NMSettings *settings, + GParamSpec *pspec, + NMManager *self) +{ + check_if_startup_complete (self); +} + +static void remove_device (NMManager *manager, NMDevice *device, gboolean quitting, @@ -1020,6 +1028,7 @@ get_virtual_iface_name (NMManager *self, * system_create_virtual_device: * @self: the #NMManager * @connection: the connection which might require a virtual device + * @error: the error set when return value is NULL * * If @connection requires a virtual device and one does not yet exist for it, * creates that device. @@ -1027,19 +1036,27 @@ get_virtual_iface_name (NMManager *self, * Returns: the #NMDevice if successfully created, %NULL if not */ static NMDevice * -system_create_virtual_device (NMManager *self, NMConnection *connection) +system_create_virtual_device (NMManager *self, NMConnection *connection, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *error = NULL; + GError *local_err = NULL; GSList *iter; char *iface = NULL; NMDevice *device = NULL, *parent = NULL; gboolean nm_owned = FALSE; + g_return_val_if_fail (NM_IS_MANAGER (self), NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + iface = get_virtual_iface_name (self, connection, &parent); if (!iface) { nm_log_dbg (LOGD_DEVICE, "(%s) failed to determine virtual interface name", nm_connection_get_id (connection)); + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "failed to determine virtual interface name"); return NULL; } @@ -1048,8 +1065,15 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) NMDevice *candidate = iter->data; if ( g_strcmp0 (nm_device_get_iface (candidate), iface) == 0 - || nm_device_check_connection_compatible (candidate, connection)) + || nm_device_check_connection_compatible (candidate, connection)) { + nm_log_dbg (LOGD_DEVICE, "(%s) already created virtual interface name %s", + nm_connection_get_id (connection), iface); + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "interface name '%s' already created", iface); goto out; + } } /* Block notification of link added since we're creating the device @@ -1064,14 +1088,15 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) device = nm_device_factory_create_virtual_device_for_connection (NM_DEVICE_FACTORY (iter->data), connection, parent, - &error); - if (device || error) { + &local_err); + if (device || local_err) { if (device) - g_assert_no_error (error); + g_assert_no_error (local_err); else { nm_log_err (LOGD_DEVICE, "(%s) failed to create virtual device: %s", - nm_connection_get_id (connection), error ? error->message : "(unknown error)"); - g_clear_error (&error); + nm_connection_get_id (connection), + local_err ? local_err->message : "(unknown error)"); + g_propagate_error (error, local_err); } break; } @@ -1087,6 +1112,16 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) add_device (self, device, !nm_owned); g_object_unref (device); + } else { + if (error && !*error) + nm_log_err (LOGD_DEVICE, "(%s:%s) NetworkManager plugin for '%s' unavailable", + nm_connection_get_id (connection), iface, + nm_connection_get_connection_type (connection)); + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "NetworkManager plugin for '%s' unavailable", + nm_connection_get_connection_type (connection)); } priv->ignore_link_added_cb--; @@ -1111,7 +1146,7 @@ system_create_virtual_devices (NMManager *self) /* We only create a virtual interface if the connection can autoconnect */ if ( nm_connection_is_virtual (connection) && nm_settings_connection_can_autoconnect (NM_SETTINGS_CONNECTION (connection))) - system_create_virtual_device (self, connection); + system_create_virtual_device (self, connection, NULL); } g_slist_free (connections); } @@ -1128,7 +1163,7 @@ connection_added (NMSettings *settings, g_assert (s_con); if (nm_setting_connection_get_autoconnect (s_con)) - system_create_virtual_device (manager, connection); + system_create_virtual_device (manager, connection, NULL); } } @@ -1498,6 +1533,9 @@ done: static gboolean match_connection_filter (NMConnection *connection, gpointer user_data) { + if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + return FALSE; + return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection); } @@ -2491,7 +2529,7 @@ ensure_master_active_connection (NMManager *self, if (!is_compatible_with_slave (candidate, connection)) continue; - if (nm_device_connection_is_available (master_device, candidate, TRUE)) { + if (nm_device_check_connection_available (master_device, candidate, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { master_ac = nm_manager_activate_connection (self, candidate, NULL, @@ -2532,7 +2570,7 @@ ensure_master_active_connection (NMManager *self, continue; } - if (!nm_device_connection_is_available (candidate, master_connection, TRUE)) + if (!nm_device_check_connection_available (candidate, master_connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) continue; found_device = TRUE; @@ -2601,6 +2639,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * NMConnection *connection; NMConnection *master_connection = NULL; NMActiveConnection *master_ac = NULL; + GError *local_err = NULL; g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); @@ -2625,12 +2664,14 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * return FALSE; } - device = system_create_virtual_device (self, connection); + device = system_create_virtual_device (self, connection, &local_err); if (!device) { - g_set_error_literal (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "Failed to create virtual interface"); + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Failed to create virtual interface: %s", + local_err ? local_err->message : "(unknown)"); + g_clear_error (&local_err); return FALSE; } @@ -2646,7 +2687,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * * in the UNAVAILABLE state here. To ensure it can be activated * immediately, we transition it to DISCONNECTED. */ - if ( nm_device_is_available (device) + if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE) && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) { nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, @@ -2680,7 +2721,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Final connection must be available on device */ - if (!nm_device_connection_is_available (device, connection, TRUE)) { + if (!nm_device_check_connection_available (device, connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "Connection '%s' is not available on the device %s at this time.", nm_connection_get_id (connection), nm_device_get_iface (device)); @@ -3589,7 +3630,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed) waking_from_suspend = sleeping_changed && !priv->sleeping; if (manager_sleeping (self)) { - nm_log_info (LOGD_SUSPEND, suspending ? "sleeping..." : "disabling..."); + nm_log_info (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling"); /* FIXME: are there still hardware devices that need to be disabled around * suspend/resume? @@ -3607,7 +3648,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed) nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_SLEEPING); } } else { - nm_log_info (LOGD_SUSPEND, waking_from_suspend ? "waking up..." : "re-enabling..."); + nm_log_info (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling"); if (waking_from_suspend) { /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this @@ -4721,6 +4762,8 @@ nm_manager_new (NMSettings *settings, priv->prop_filter_added = TRUE; priv->settings = g_object_ref (settings); + g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE, + G_CALLBACK (settings_startup_complete_changed), singleton); priv->state_file = g_strdup (state_file); @@ -4795,7 +4838,7 @@ nm_manager_init (NMManager *manager) priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN; priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE; - priv->radio_states[RFKILL_TYPE_WIMAX].key = "WiMAXEnabled"; + priv->radio_states[RFKILL_TYPE_WIMAX].key = "WimaxEnabled"; priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED; priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED; priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX"; @@ -5038,6 +5081,7 @@ dispose (GObject *object) } g_clear_object (&priv->settings); + g_free (priv->state_file); g_clear_object (&priv->vpn_manager); /* Unregister property filter */ diff --git a/src/nm-properties-changed-signal.c b/src/nm-properties-changed-signal.c index 7ba62aa2..c6dbb3d5 100644 --- a/src/nm-properties-changed-signal.c +++ b/src/nm-properties-changed-signal.c @@ -148,8 +148,8 @@ notify (GObject *object, GParamSpec *pspec) break; } if (!dbus_property_name) { - nm_log_dbg (LOGD_DBUS_PROPS, "ignoring notification for prop %s on type %s", - pspec->name, G_OBJECT_TYPE_NAME (object)); + nm_log_trace (LOGD_DBUS_PROPS, "ignoring notification for prop %s on type %s", + pspec->name, G_OBJECT_TYPE_NAME (object)); return; } @@ -228,16 +228,21 @@ nm_properties_changed_signal_add_property (GType type, if (!classinfo) classinfo = nm_properties_changed_signal_setup_type (type); + g_assert (!g_hash_table_contains (classinfo->exported_props, (char *) gobject_property_name)); g_hash_table_insert (classinfo->exported_props, (char *) gobject_property_name, (char *) dbus_property_name); + if (!strchr (gobject_property_name, '_')) + return; hyphen_name = g_strdup (gobject_property_name); for (p = hyphen_name; *p; p++) { if (*p == '_') *p = '-'; } + g_assert (!g_hash_table_contains (classinfo->exported_props, hyphen_name)); g_hash_table_insert (classinfo->exported_props, - hyphen_name, + (char *) g_intern_string (hyphen_name), (char *) dbus_property_name); + g_free (hyphen_name); } diff --git a/src/platform/Makefile.in b/src/platform/Makefile.in index d4c8ade7..a41de1ae 100644 --- a/src/platform/Makefile.in +++ b/src/platform/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,7 +88,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/platform -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -95,6 +104,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -154,6 +164,7 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -205,7 +216,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -240,6 +250,7 @@ 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@ @@ -456,7 +467,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/platform/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/platform/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -751,6 +761,8 @@ uninstall-am: mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + # 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/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index a5eb7d4e..7b0d2d64 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -456,6 +456,15 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex) return NULL; } +static guint +link_get_dev_id (NMPlatform *platform, int ifindex) +{ + /* We call link_get just to cause an error to be set if @ifindex is bad. */ + link_get (platform, ifindex); + + return 0; +} + static gboolean link_get_wake_on_lan (NMPlatform *platform, int ifindex) { @@ -1076,6 +1085,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, continue; if (item->plen != route.plen) continue; + if (item->metric != metric) + continue; memcpy (item, &route, sizeof (route)); g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, ifindex, &route, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL); @@ -1097,6 +1108,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, NMPlatformIP6Route route; guint i; + metric = nm_utils_ip6_route_metric_normalize (metric); + memset (&route, 0, sizeof (route)); route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; @@ -1116,6 +1129,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, continue; if (item->plen != route.plen) continue; + if (item->metric != metric) + continue; memcpy (item, &route, sizeof (route)); g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, ifindex, &route, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL); @@ -1153,6 +1168,8 @@ ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int p NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; + metric = nm_utils_ip6_route_metric_normalize (metric); + for (i = 0; i < priv->ip6_routes->len; i++) { NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i); @@ -1301,6 +1318,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->link_set_mtu = link_set_mtu; platform_class->link_get_physical_port_id = link_get_physical_port_id; + platform_class->link_get_dev_id = link_get_dev_id; platform_class->link_get_wake_on_lan = link_get_wake_on_lan; platform_class->link_supports_carrier_detect = link_supports_carrier_detect; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 5d1522ce..c337ee9c 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -127,7 +127,7 @@ _nl_get_vtable (void) if (G_UNLIKELY (!vtable.f_nl_has_capability)) { void *handle; - handle = dlopen ("libnl-3.so", RTLD_LAZY | RTLD_NOLOAD); + handle = dlopen ("libnl-3.so.200", RTLD_LAZY | RTLD_NOLOAD); if (handle) { vtable.handle = handle; vtable.f_nl_has_capability = dlsym (handle, "nl_has_capability"); @@ -872,16 +872,15 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char if (!ifname) return_type (NM_LINK_TYPE_UNKNOWN, type); + driver = ethtool_get_driver (ifname); if (arptype == 256) { /* Some s390 CTC-type devices report 256 for the encapsulation type - * for some reason, but we need to call them Ethernet. FIXME: use - * something other than interface name to detect CTC here. + * for some reason, but we need to call them Ethernet. */ - if (g_str_has_prefix (ifname, "ctc")) + if (!g_strcmp0 (driver, "ctcm")) return_type (NM_LINK_TYPE_ETHERNET, "ethernet"); } - driver = ethtool_get_driver (ifname); if (!g_strcmp0 (driver, "openvswitch")) return_type (NM_LINK_TYPE_OPENVSWITCH, "openvswitch"); @@ -1008,7 +1007,7 @@ init_link (NMPlatform *platform, NMPlatformLink *info, struct rtnl_link *rtnllin if (udev_device) { info->driver = udev_get_driver (platform, udev_device, info->ifindex); if (!info->driver) - info->driver = rtnl_link_get_type (rtnllink); + info->driver = g_intern_string (rtnl_link_get_type (rtnllink)); if (!info->driver) info->driver = ethtool_get_driver (info->name); if (!info->driver) @@ -1392,7 +1391,6 @@ static char to_string_buffer[255]; #define SET_AND_RETURN_STRING_BUFFER(...) \ G_STMT_START { \ g_snprintf (to_string_buffer, sizeof (to_string_buffer), ## __VA_ARGS__); \ - g_return_val_if_reached (to_string_buffer); \ return to_string_buffer; \ } G_STMT_END @@ -1668,6 +1666,9 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP4Route route; + if (reason == _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL) + return; + if (!_route_match ((struct rtnl_route *) object, AF_INET, 0, FALSE)) { nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP4 route %s", to_string_ip4_route ((struct rtnl_route *) object)); return; @@ -1680,6 +1681,9 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP6Route route; + if (reason == _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL) + return; + if (!_route_match ((struct rtnl_route *) object, AF_INET6, 0, FALSE)) { nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP6 route %s", to_string_ip6_route ((struct rtnl_route *) object)); return; @@ -1719,9 +1723,15 @@ refresh_object (NMPlatform *platform, struct nl_object *object, gboolean removed announce_object (platform, cached_object, NM_PLATFORM_SIGNAL_REMOVED, reason); } } else { + ObjectType type; + if (!kernel_object) return FALSE; + /* Unsupported object types should never have reached the caches */ + type = object_type_from_nl_object (kernel_object); + g_assert (type != OBJECT_TYPE_UNKNOWN); + hack_empty_master_iff_lower_up (platform, kernel_object); if (cached_object) @@ -1735,7 +1745,7 @@ refresh_object (NMPlatform *platform, struct nl_object *object, gboolean removed announce_object (platform, kernel_object, cached_object ? NM_PLATFORM_SIGNAL_CHANGED : NM_PLATFORM_SIGNAL_ADDED, reason); /* Refresh the master device (even on enslave/release) */ - if (object_type_from_nl_object (kernel_object) == OBJECT_TYPE_LINK) { + if (type == OBJECT_TYPE_LINK) { int kernel_master = rtnl_link_get_master ((struct rtnl_link *) kernel_object); int cached_master = cached_object ? rtnl_link_get_master ((struct rtnl_link *) cached_object) : 0; struct nl_object *master_object; @@ -1763,10 +1773,6 @@ add_object (NMPlatform *platform, struct nl_object *obj) auto_nl_object struct nl_object *object = obj; NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); int nle; - struct nl_dump_params dp = { - .dp_type = NL_DUMP_DETAILS, - .dp_fd = stderr, - }; g_return_val_if_fail (object, FALSE); @@ -1782,7 +1788,18 @@ add_object (NMPlatform *platform, struct nl_object *obj) break; default: error ("Netlink error adding %s: %s", to_string_object (platform, object), nl_geterror (nle)); - nl_object_dump (object, &dp); + if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { + char buf[256]; + struct nl_dump_params dp = { + .dp_type = NL_DUMP_DETAILS, + .dp_buf = buf, + .dp_buflen = sizeof (buf), + }; + + nl_object_dump (object, &dp); + buf[sizeof (buf) - 1] = '\0'; + debug ("netlink object:\n%s", buf); + } return FALSE; } @@ -1997,6 +2014,11 @@ event_notification (struct nl_msg *msg, gpointer user_data) */ if (!kernel_object) return NL_OK; + + /* Ignore unsupported object types (e.g. AF_PHONET family addresses) */ + if (type == OBJECT_TYPE_UNKNOWN) + return NL_OK; + /* Handle external addition */ if (!cached_object) { nle = nl_cache_add (cache, kernel_object); @@ -2690,6 +2712,30 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex) return id; } +static guint +link_get_dev_id (NMPlatform *platform, int ifindex) +{ + const char *ifname; + gs_free char *path = NULL, *id = NULL; + gint64 int_val; + + ifname = nm_platform_link_get_name (ifindex); + if (!ifname) + return 0; + + ifname = ASSERT_VALID_PATH_COMPONENT (ifname); + + path = g_strdup_printf ("/sys/class/net/%s/dev_id", ifname); + id = sysctl_get (platform, path); + if (!id || !*id) + return 0; + + /* Value is reported as hex */ + int_val = nm_utils_ascii_str_to_int64 (id, 16, 0, G_MAXUINT16, 0); + + return errno ? 0 : (int) int_val; +} + static int vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint32 vlan_flags) { @@ -3507,7 +3553,7 @@ build_rtnl_addr (int family, guint flags, const char *label) { - auto_nl_addr struct rtnl_addr *rtnladdr = _nm_rtnl_addr_alloc (ifindex); + auto_nl_object struct rtnl_addr *rtnladdr = _nm_rtnl_addr_alloc (ifindex); struct rtnl_addr *rtnladdr_copy; int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); auto_nl_addr struct nl_addr *nladdr = _nm_nl_addr_build (family, addr, addrlen); @@ -3698,6 +3744,7 @@ _route_match (struct rtnl_route *rtnlroute, int family, int ifindex, gboolean in if (rtnl_route_get_type (rtnlroute) != RTN_UNICAST || rtnl_route_get_table (rtnlroute) != RT_TABLE_MAIN || + rtnl_route_get_tos (rtnlroute) != 0 || (!include_proto_kernel && rtnl_route_get_protocol (rtnlroute) == RTPROT_KERNEL) || rtnl_route_get_family (rtnlroute) != family || rtnl_route_get_nnexthops (rtnlroute) != 1 || @@ -3845,6 +3892,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, guint32 metric, guint32 mss) { + metric = nm_utils_ip6_route_metric_normalize (metric); + return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, NULL, metric, mss)); } @@ -3863,7 +3912,7 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void if (!_route_match (rtnlroute, family, ifindex, FALSE)) continue; - if (metric && metric != rtnl_route_get_priority (rtnlroute)) + if (metric != rtnl_route_get_priority (rtnlroute)) continue; dst = rtnl_route_get_dst (rtnlroute); @@ -3872,7 +3921,14 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void || nl_addr_get_prefixlen (dst) != plen) continue; - clear_host_address (family, nl_addr_get_binary_addr (dst), plen, dst_clean); + /* plen = 0 means all host bits, so all bits should be cleared. + * Likewise if the binary address is not present or all zeros. + */ + if (plen == 0 || nl_addr_iszero (dst)) + memset (dst_clean, 0, sizeof (dst_clean)); + else + clear_host_address (family, nl_addr_get_binary_addr (dst), plen, dst_clean); + if (memcmp (dst_clean, network_clean, family == AF_INET ? sizeof (guint32) : sizeof (struct in6_addr)) != 0) continue; @@ -3884,7 +3940,7 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void } static gboolean -refresh_route (NMPlatform *platform, int family, int ifindex, const void *network, int plen, int metric) +refresh_route (NMPlatform *platform, int family, int ifindex, const void *network, int plen, guint32 metric) { struct nl_cache *cache; auto_nl_object struct rtnl_route *cached_object = NULL; @@ -3910,6 +3966,19 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen cache = choose_cache_by_type (platform, OBJECT_TYPE_IP4_ROUTE); + if (metric == 0) { + /* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route. + * If no route with metric 0 exists, it might delete another route to the same destination. + * For nm_platform_ip4_route_delete() we don't want this semantic. + * + * Instead, re-fetch the route from kernel, and if that fails, there is nothing to do. + * On success, there is still a race that we might end up deleting the wrong route. */ + if (!refresh_object (platform, (struct nl_object *) route, FALSE, _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL)) { + rtnl_route_put ((struct rtnl_route *) route); + return TRUE; + } + } + /* when deleting an IPv4 route, several fields of the provided route must match. * Lookup in the cache so that we hopefully get the right values. */ cached_object = (struct rtnl_route *) nl_cache_search (cache, route); @@ -3943,8 +4012,8 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } rtnl_route_set_scope ((struct rtnl_route *) route, scope); - if (cached_object) - rtnl_route_set_tos ((struct rtnl_route *) route, rtnl_route_get_tos (cached_object)); + /* we only support routes with TOS zero. As such, delete_route() is also only able to delete + * routes with tos==0. build_rtnl_route() already initializes tos properly. */ /* The following fields are also relevant when comparing the route, but the default values * are already as we want them: @@ -3962,6 +4031,8 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in { struct in6_addr gateway = IN6ADDR_ANY_INIT; + metric = nm_utils_ip6_route_metric_normalize (metric); + return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN ,&network, plen, &gateway, NULL, metric, 0), FALSE) && refresh_route (platform, AF_INET6, ifindex, &network, plen, metric); } @@ -3989,6 +4060,8 @@ ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen static gboolean ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { + metric = nm_utils_ip6_route_metric_normalize (metric); + return ip_route_exists (platform, AF_INET6, ifindex, &network, plen, metric); } @@ -4061,6 +4134,33 @@ cache_announce_changes (NMPlatform *platform, struct nl_cache *new, struct nl_ca nl_cache_free (old); } +/* The cache should always avoid containing objects not handled by NM, like + * e.g. addresses of the AF_PHONET family. */ +static void +cache_remove_unknown (struct nl_cache *cache) +{ + GPtrArray *objects_to_remove = NULL; + struct nl_object *object; + + for (object = nl_cache_get_first (cache); object; object = nl_cache_get_next (object)) { + if (object_type_from_nl_object (object) == OBJECT_TYPE_UNKNOWN) { + if (!objects_to_remove) + objects_to_remove = g_ptr_array_new_with_free_func ((GDestroyNotify) nl_object_put); + nl_object_get (object); + g_ptr_array_add (objects_to_remove, object); + } + } + + if (objects_to_remove) { + guint i; + + for (i = 0; i < objects_to_remove->len; i++) + nl_cache_remove (g_ptr_array_index (objects_to_remove, i)); + + g_ptr_array_free (objects_to_remove, TRUE); + } +} + /* Creates and populates the netlink object caches. Called upon platform init and * when we run out of sync (out of buffer space, netlink congestion control). In case * the caches already exist, it finds changed, added and removed objects, announces @@ -4082,6 +4182,11 @@ cache_repopulate_all (NMPlatform *platform) rtnl_route_alloc_cache (priv->nlh, AF_UNSPEC, 0, &priv->route_cache); g_assert (priv->link_cache && priv->address_cache && priv->route_cache); + /* Remove all unknown objects from the caches */ + cache_remove_unknown (priv->link_cache); + cache_remove_unknown (priv->address_cache); + cache_remove_unknown (priv->route_cache); + for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) { _rtnl_addr_hack_lifetimes_rel_to_abs ((struct rtnl_addr *) object); } @@ -4139,7 +4244,13 @@ event_handler (GIOChannel *channel, * like to free up some space. We'll read in the status synchronously. */ nl_socket_modify_cb (priv->nlh_event, NL_CB_VALID, NL_CB_DEFAULT, NULL, NULL); do { + errno = 0; + nle = nl_recvmsgs_default (priv->nlh_event); + + /* Work around a libnl bug fixed in 3.2.22 (375a6294) */ + if (nle == 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) + nle = -NLE_AGAIN; } while (nle != -NLE_AGAIN); nl_socket_modify_cb (priv->nlh_event, NL_CB_VALID, NL_CB_CUSTOM, event_notification, user_data); cache_repopulate_all (platform); @@ -4473,6 +4584,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_set_mtu = link_set_mtu; platform_class->link_get_physical_port_id = link_get_physical_port_id; + platform_class->link_get_dev_id = link_get_dev_id; platform_class->link_get_wake_on_lan = link_get_wake_on_lan; platform_class->link_supports_carrier_detect = link_supports_carrier_detect; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 14fc44c5..ba7708d6 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -258,6 +258,38 @@ nm_platform_sysctl_set (const char *path, const char *value) return klass->sysctl_set (platform, path, value); } +gboolean +nm_platform_sysctl_set_ip6_hop_limit_safe (const char *iface, int value) +{ + const char *path; + gint64 cur; + + /* the hop-limit provided via RA is uint8. */ + if (value > 0xFF) + return FALSE; + + /* don't allow unreasonable small values */ + if (value < 10) + return FALSE; + + path = nm_utils_ip6_property_path (iface, "hop_limit"); + cur = nm_platform_sysctl_get_int_checked (path, 10, 1, G_MAXINT32, -1); + + /* only allow increasing the hop-limit to avoid DOS by an attacker + * setting a low hop-limit (CVE-2015-2924, rh#1209902) */ + + if (value < cur) + return FALSE; + if (value != cur) { + char svalue[20]; + + sprintf (svalue, "%d", value); + nm_platform_sysctl_set (path, svalue); + } + + return TRUE; +} + /** * nm_platform_sysctl_get: * @path: Absolute path to sysctl @@ -963,9 +995,15 @@ nm_platform_link_get_mtu (int ifindex) } /** - * nm_platform_link_get_mtu: + * nm_platform_link_get_physical_port_id: * @ifindex: Interface index * + * The physical port ID, if present, indicates some unique identifier of + * the parent interface (eg, the physical port of which this link is a child). + * Two links that report the same physical port ID can be assumed to be + * children of the same physical port and may share resources that limit + * their abilities. + * * Returns: physical port ID for the interface, or %NULL on error * or if the interface has no physical port ID. */ @@ -981,6 +1019,28 @@ nm_platform_link_get_physical_port_id (int ifindex) } /** + * nm_platform_link_get_dev_id: + * @ifindex: Interface index + * + * In contrast to the physical device ID (which indicates which parent a + * child has) the device ID differentiates sibling devices that may share + * the same MAC address. + * + * Returns: device ID for the interface, or 0 on error or if the + * interface has no device ID. + */ +guint +nm_platform_link_get_dev_id (int ifindex) +{ + reset_error (); + + g_return_val_if_fail (ifindex >= 0, 0); + g_return_val_if_fail (klass->link_get_dev_id, 0); + + return klass->link_get_dev_id (platform, ifindex); +} + +/** * nm_platform_link_get_wake_onlan: * @ifindex: Interface index * @@ -1826,6 +1886,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses, guint3 * nm_platform_ip6_address_sync: * @ifindex: Interface index * @known_addresses: List of addresses + * @keep_link_local: Don't remove link-local address * * A convenience function to synchronize addresses for a specific interface * with the least possible disturbance. It simply removes addresses that are @@ -1834,7 +1895,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses, guint3 * Returns: %TRUE on success. */ gboolean -nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) +nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses, gboolean keep_link_local) { GArray *addresses; NMPlatformIP6Address *address; @@ -1847,7 +1908,7 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) address = &g_array_index (addresses, NMPlatformIP6Address, i); /* Leave link local address management to the kernel */ - if (IN6_IS_ADDR_LINKLOCAL (&address->address)) + if (keep_link_local && IN6_IS_ADDR_LINKLOCAL (&address->address)) continue; if (!array_contains_ip6_address (known_addresses, address)) @@ -1880,7 +1941,7 @@ gboolean nm_platform_address_flush (int ifindex) { return nm_platform_ip4_address_sync (ifindex, NULL, 0) - && nm_platform_ip6_address_sync (ifindex, NULL); + && nm_platform_ip6_address_sync (ifindex, NULL, FALSE); } /******************************************************************/ @@ -2100,7 +2161,8 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route)) continue; - if ((known_route->gateway == 0) ^ (i_type != 0)) { + if ( (i_type == 0 && known_route->gateway != 0) + || (i_type == 1 && known_route->gateway == 0)) { /* Make two runs over the list of routes. On the first, only add * device routes, on the second the others (gateway routes). */ continue; @@ -2174,7 +2236,8 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route)) continue; - if (IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway) ^ (i_type != 0)) { + if ( (i_type == 0 && !IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway)) + || (i_type == 1 && IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway))) { /* Make two runs over the list of routes. On the first, only add * device routes, on the second the others (gateway routes). */ continue; @@ -2738,6 +2801,97 @@ log_ip6_route (NMPlatform *p, int ifindex, NMPlatformIP6Route *route, NMPlatform /******************************************************************/ +static gboolean +_vtr_v4_route_add (int ifindex, const NMPlatformIPXRoute *route, guint32 v4_pref_src) +{ + return nm_platform_ip4_route_add (ifindex > 0 ? ifindex : route->rx.ifindex, + route->rx.source, + route->r4.network, + route->rx.plen, + route->r4.gateway, + v4_pref_src, + route->rx.metric, + route->rx.mss); +} + +static gboolean +_vtr_v6_route_add (int ifindex, const NMPlatformIPXRoute *route, guint32 v4_pref_src) +{ + return nm_platform_ip6_route_add (ifindex > 0 ? ifindex : route->rx.ifindex, + route->rx.source, + route->r6.network, + route->rx.plen, + route->r6.gateway, + route->rx.metric, + route->rx.mss); +} + +static gboolean +_vtr_v4_route_delete (int ifindex, const NMPlatformIPXRoute *route) +{ + return nm_platform_ip4_route_delete (ifindex > 0 ? ifindex : route->rx.ifindex, + route->r4.network, + route->rx.plen, + route->rx.metric); +} + +static gboolean +_vtr_v6_route_delete (int ifindex, const NMPlatformIPXRoute *route) +{ + return nm_platform_ip6_route_delete (ifindex > 0 ? ifindex : route->rx.ifindex, + route->r6.network, + route->rx.plen, + route->rx.metric); +} + +static guint32 +_vtr_v4_metric_normalize (guint32 metric) +{ + return metric; +} + +static gboolean +_vtr_v4_route_delete_default (int ifindex, guint32 metric) +{ + return nm_platform_ip4_route_delete (ifindex, 0, 0, metric); +} + +static gboolean +_vtr_v6_route_delete_default (int ifindex, guint32 metric) +{ + return nm_platform_ip6_route_delete (ifindex, in6addr_any, 0, metric); +} + +/******************************************************************/ + +const NMPlatformVTableRoute nm_platform_vtable_route_v4 = { + .is_ip4 = TRUE, + .addr_family = AF_INET, + .sizeof_route = sizeof (NMPlatformIP4Route), + .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b)) nm_platform_ip4_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route)) nm_platform_ip4_route_to_string, + .route_get_all = nm_platform_ip4_route_get_all, + .route_add = _vtr_v4_route_add, + .route_delete = _vtr_v4_route_delete, + .route_delete_default = _vtr_v4_route_delete_default, + .metric_normalize = _vtr_v4_metric_normalize, +}; + +const NMPlatformVTableRoute nm_platform_vtable_route_v6 = { + .is_ip4 = FALSE, + .addr_family = AF_INET6, + .sizeof_route = sizeof (NMPlatformIP6Route), + .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b)) nm_platform_ip6_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route)) nm_platform_ip6_route_to_string, + .route_get_all = nm_platform_ip6_route_get_all, + .route_add = _vtr_v6_route_add, + .route_delete = _vtr_v6_route_delete, + .route_delete_default = _vtr_v6_route_delete_default, + .metric_normalize = nm_utils_ip6_route_metric_normalize, +}; + +/******************************************************************/ + static void nm_platform_init (NMPlatform *object) { diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 848f78e4..a49e0f11 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -69,7 +69,10 @@ typedef enum { /* Event came from the kernel. */ NM_PLATFORM_REASON_EXTERNAL, /* Event is a result of cache checking and cleanups. */ - NM_PLATFORM_REASON_CACHE_CHECK + NM_PLATFORM_REASON_CACHE_CHECK, + + /* Internal reason to suppress announcing change events */ + _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL, } NMPlatformReason; #define __NMPlatformObject_COMMON \ @@ -244,6 +247,23 @@ typedef union { typedef struct { + gboolean is_ip4; + int addr_family; + gsize sizeof_route; + int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b); + const char *(*route_to_string) (const NMPlatformIPXRoute *route); + GArray *(*route_get_all) (int ifindex, NMPlatformGetRouteMode mode); + gboolean (*route_add) (int ifindex, const NMPlatformIPXRoute *route, guint32 v4_pref_src); + gboolean (*route_delete) (int ifindex, const NMPlatformIPXRoute *route); + gboolean (*route_delete_default) (int ifindex, guint32 metric); + guint32 (*metric_normalize) (guint32 metric); +} NMPlatformVTableRoute; + +extern const NMPlatformVTableRoute nm_platform_vtable_route_v4; +extern const NMPlatformVTableRoute nm_platform_vtable_route_v6; + + +typedef struct { int peer; } NMPlatformVethProperties; @@ -367,7 +387,8 @@ typedef struct { guint32 (*link_get_mtu) (NMPlatform *, int ifindex); gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); - char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); + char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); + guint (*link_get_dev_id) (NMPlatform *, int ifindex); gboolean (*link_get_wake_on_lan) (NMPlatform *, int ifindex); gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex); @@ -480,6 +501,8 @@ char *nm_platform_sysctl_get (const char *path); gint32 nm_platform_sysctl_get_int32 (const char *path, gint32 fallback); gint64 nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64 min, gint64 max, gint64 fallback); +gboolean nm_platform_sysctl_set_ip6_hop_limit_safe (const char *iface, int value); + gboolean nm_platform_link_get (int ifindex, NMPlatformLink *link); GArray *nm_platform_link_get_all (void); gboolean nm_platform_dummy_add (const char *name); @@ -514,6 +537,7 @@ guint32 nm_platform_link_get_mtu (int ifindex); gboolean nm_platform_link_set_mtu (int ifindex, guint32 mtu); char *nm_platform_link_get_physical_port_id (int ifindex); +guint nm_platform_link_get_dev_id (int ifindex); gboolean nm_platform_link_get_wake_on_lan (int ifindex); gboolean nm_platform_link_supports_carrier_detect (int ifindex); @@ -569,7 +593,7 @@ gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, i gboolean nm_platform_ip4_address_exists (int ifindex, in_addr_t address, int plen); gboolean nm_platform_ip6_address_exists (int ifindex, struct in6_addr address, int plen); gboolean nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses, guint32 device_route_metric); -gboolean nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses); +gboolean nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses, gboolean keep_link_local); gboolean nm_platform_address_flush (int ifindex); gboolean nm_platform_ip4_check_reinstall_device_route (int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric); diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index b06e25e0..c10600eb 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -109,7 +109,7 @@ test_cleanup_linux_CPPFLAGS = \ -DKERNEL_HACKS=1 test_cleanup_linux_LDADD = $(PLATFORM_LDADD) -#@VALGRIND_RULES@ +@VALGRIND_RULES@ TESTS = test-link-fake test-address-fake test-route-fake test-cleanup-fake test-address-linux test-route-linux test-cleanup-linux diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in index 052636ab..16a48430 100644 --- a/src/platform/tests/Makefile.in +++ b/src/platform/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -89,8 +99,6 @@ TESTS = test-link-fake$(EXEEXT) test-address-fake$(EXEEXT) \ test-address-linux$(EXEEXT) test-route-linux$(EXEEXT) \ test-cleanup-linux$(EXEEXT) subdir = src/platform/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -107,6 +115,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -289,6 +298,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -315,7 +326,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -350,6 +360,7 @@ 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@ @@ -647,7 +658,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/platform/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/platform/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -777,14 +787,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1698,9 +1708,13 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ +@VALGRIND_RULES@ + # 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. .NOEXPORT: diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 3ef13b8e..5561038d 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -247,6 +247,12 @@ test_ip6_address_external (void) } void +init_tests (int *argc, char ***argv) +{ + nmtst_init_with_logging (argc, argv, NULL, "ALL"); +} + +void setup_tests (void) { SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index afbb438c..0d0f3f63 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -87,6 +87,12 @@ test_cleanup_internal (void) } void +init_tests (int *argc, char ***argv) +{ + nmtst_init_with_logging (argc, argv, NULL, "ALL"); +} + +void setup_tests (void) { nm_platform_link_delete (nm_platform_link_get_ifindex (DEVICE_NAME)); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index ab40f652..1980282d 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -125,6 +125,113 @@ link_callback (NMPlatform *platform, int ifindex, NMPlatformLink *received, NMPl g_error ("Added/changed link not found in the local cache."); } +gboolean +ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) +{ + gs_free char *arg_network = NULL; + const char *argv[] = { + NULL, + "route", + "list", + "dev", + ifname, + "exact", + NULL, + NULL, + }; + int exit_status; + gs_free char *std_out = NULL, *std_err = NULL; + char *out; + gboolean success; + gs_free_error GError *error = NULL; + gs_free char *metric_pattern = NULL; + + g_assert (ifname && nm_utils_iface_valid_name (ifname)); + g_assert (!strstr (ifname, " metric ")); + g_assert (plen >= 0 && plen <= 32); + + if (!NM_IS_LINUX_PLATFORM (nm_platform_get ())) { + /* If we don't test against linux-platform, we don't actually configure any + * routes in the system. */ + return -1; + } + + argv[0] = nm_utils_file_search_in_paths ("ip", NULL, + (const char *[]) { "/sbin", "/usr/sbin", NULL }, + G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, NULL); + argv[6] = arg_network = g_strdup_printf ("%s/%d", nm_utils_inet4_ntop (network, NULL), plen); + + if (!argv[0]) { + /* Hm. There is no 'ip' binary. Return *unknown* */ + return -1; + } + + success = g_spawn_sync (NULL, + (char **) argv, + (char *[]) { NULL }, + 0, + NULL, + NULL, + &std_out, + &std_err, + &exit_status, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpstr (std_err, ==, ""); + g_assert (std_out); + + metric_pattern = g_strdup_printf (" metric %u", metric); + out = std_out; + while (out) { + char *eol = strchr (out, '\n'); + gs_free char *line = eol ? g_strndup (out, eol - out) : g_strdup (out); + const char *p; + + out = eol ? &eol[1] : NULL; + if (!line[0]) + continue; + + if (metric == 0) { + if (!strstr (line, " metric ")) + return TRUE; + } + p = strstr (line, metric_pattern); + if (p && NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0')) + return TRUE; + } + return FALSE; +} + +void +_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) +{ + int ifindex; + gboolean exists_checked; + + /* Check for existance of the route by spawning iproute2. Do this because platform + * code might be entirely borked, but we expect ip-route to give a correct result. + * If the ip command cannot be found, we accept this as success. */ + exists_checked = ip4_route_exists (ifname, network, plen, metric); + if (exists_checked != -1 && !exists_checked != !exists) { + g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s", + file, line, func, + nm_utils_inet4_ntop (network, NULL), plen, metric, + exists ? "to exist" : "not to exist", + exists ? "doesn't" : "does"); + } + + ifindex = nm_platform_link_get_ifindex (ifname); + g_assert (ifindex > 0); + if (!nm_platform_ip4_route_exists (ifindex, network, plen, metric) != !exists) { + g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s", + file, line, func, + nm_utils_inet4_ntop (network, NULL), plen, metric, + exists ? "exists" : "does not exist", + exists ? "it doesn't" : "it does"); + } +} + void run_command (const char *format, ...) { @@ -148,20 +255,22 @@ main (int argc, char **argv) int result; const char *program = *argv; - nmtst_init_with_logging (&argc, &argv, NULL, "ALL"); + init_tests (&argc, &argv); + NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare") if (SETUP == nm_linux_platform_setup && getuid() != 0) { /* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */ nmtst_reexec_sudo (); #ifdef REQUIRE_ROOT_TESTS - g_message ("Fail test: requires root privileges (%s)", program); + g_print ("Fail test: requires root privileges (%s)\n", program); return EXIT_FAILURE; #else - g_message ("Skipping test: requires root privileges (%s)", program); + g_print ("Skipping test: requires root privileges (%s)\n", program); return 77; #endif } + NM_PRAGMA_WARNING_REENABLE SETUP (); diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 8f6b3912..367833d1 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -9,6 +9,8 @@ #include "nm-fake-platform.h" #include "nm-linux-platform.h" +#include "nm-test-utils.h" + #define DEVICE_NAME "nm-test-device" #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) @@ -34,9 +36,15 @@ void accept_signal (SignalData *data); void wait_signal (SignalData *data); void free_signal (SignalData *data); +gboolean ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); + +void _assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); +#define assert_ip4_route_exists(exists, ifname, network, plen, metric) _assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) + void link_callback (NMPlatform *platform, int ifindex, NMPlatformLink *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data); void run_command (const char *format, ...); +void init_tests (int *argc, char ***argv); void setup_tests (void); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 8bd2ef44..99556e0a 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -365,12 +365,14 @@ test_bridge (void) static void test_bond (void) { + NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare") if (SETUP == nm_linux_platform_setup && !g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) && system("modprobe --show bonding") != 0) { g_test_skip ("Skipping test for bonding: bonding module not available"); return; } + NM_PRAGMA_WARNING_REENABLE test_software (NM_LINK_TYPE_BOND, "bond"); } @@ -538,6 +540,12 @@ test_external (void) } void +init_tests (int *argc, char ***argv) +{ + nmtst_init_with_logging (argc, argv, NULL, "ALL"); +} + +void setup_tests (void) { nm_platform_link_delete (nm_platform_link_get_ifindex (DEVICE_NAME)); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 2c70b412..2d3caaf1 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -2,6 +2,7 @@ #include "test-common.h" #include "nm-test-utils.h" +#include "NetworkManagerUtils.h" #define DEVICE_NAME "nm-test-device" @@ -50,6 +51,75 @@ ip6_route_callback (NMPlatform *platform, int ifindex, NMPlatformIP6Route *recei } static void +test_ip4_route_metric0 (void) +{ + int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); + SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_route_callback); + SignalData *route_changed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_route_callback); + SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_route_callback); + in_addr_t network = nmtst_inet4_from_string ("192.0.2.5"); /* from 192.0.2.0/24 (TEST-NET-1) (rfc5737) */ + int plen = 32; + int metric = 22987; + int mss = 1000; + + /* No routes initially */ + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + + /* add the first route */ + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss)); + no_error (); + accept_signal (route_added); + + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + + /* Deleting route with metric 0 does nothing */ + g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, 0)); + no_error (); + g_assert (!route_removed->received); + + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + + /* add the second route */ + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss)); + no_error (); + accept_signal (route_added); + + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + + /* Delete route with metric 0 */ + g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, 0)); + no_error (); + accept_signal (route_removed); + + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + + /* Delete route with metric 0 again (we expect nothing to happen) */ + g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, 0)); + no_error (); + g_assert (!route_removed->received); + + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + + /* Delete the other route */ + g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, metric)); + no_error (); + accept_signal (route_removed); + + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + + free_signal (route_added); + free_signal (route_changed); + free_signal (route_removed); +} + +static void test_ip4_route (void) { int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); @@ -74,11 +144,11 @@ test_ip4_route (void) accept_signal (route_added); /* Add route */ - g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); no_error (); g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); no_error (); - g_assert (nm_platform_ip4_route_exists (ifindex, network, plen, metric)); + assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); no_error (); accept_signal (route_added); @@ -88,11 +158,11 @@ test_ip4_route (void) accept_signal (route_changed); /* Add default route */ - g_assert (!nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); + assert_ip4_route_exists (FALSE, DEVICE_NAME, 0, 0, metric); no_error (); g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); no_error (); - g_assert (nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); + assert_ip4_route_exists (TRUE, DEVICE_NAME, 0, 0, metric); no_error (); accept_signal (route_added); @@ -127,13 +197,13 @@ test_ip4_route (void) rts[2].mss = mss; g_assert_cmpint (routes->len, ==, 3); g_assert (!memcmp (routes->data, rts, sizeof (rts))); - nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len); + nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE); g_array_unref (routes); /* Remove route */ g_assert (nm_platform_ip4_route_delete (ifindex, network, plen, metric)); no_error (); - g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); + assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); accept_signal (route_removed); /* Remove route again */ @@ -205,25 +275,25 @@ test_ip6_route (void) rts[0].plen = 128; rts[0].ifindex = ifindex; rts[0].gateway = in6addr_any; - rts[0].metric = metric; + rts[0].metric = nm_utils_ip6_route_metric_normalize (metric); rts[0].mss = mss; rts[1].source = NM_IP_CONFIG_SOURCE_USER; rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; - rts[1].metric = metric; + rts[1].metric = nm_utils_ip6_route_metric_normalize (metric); rts[1].mss = mss; rts[2].source = NM_IP_CONFIG_SOURCE_USER; rts[2].network = in6addr_any; rts[2].plen = 0; rts[2].ifindex = ifindex; rts[2].gateway = gateway; - rts[2].metric = metric; + rts[2].metric = nm_utils_ip6_route_metric_normalize (metric); rts[2].mss = mss; g_assert_cmpint (routes->len, ==, 3); g_assert (!memcmp (routes->data, rts, sizeof (rts))); - nmtst_platform_ip6_routes_equal ((NMPlatformIP6Route *) routes->data, rts, routes->len); + nmtst_platform_ip6_routes_equal ((NMPlatformIP6Route *) routes->data, rts, routes->len, TRUE); g_array_unref (routes); /* Remove route */ @@ -242,6 +312,12 @@ test_ip6_route (void) } void +init_tests (int *argc, char ***argv) +{ + nmtst_init_with_logging (argc, argv, NULL, "ALL"); +} + +void setup_tests (void) { SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); @@ -256,4 +332,5 @@ setup_tests (void) g_test_add_func ("/route/ip4", test_ip4_route); g_test_add_func ("/route/ip6", test_ip6_route); + g_test_add_func ("/route/ip4_metric0", test_ip4_route_metric0); } diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 752da926..b31ffa1c 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -738,6 +738,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) } } + /* Find number of supported frequencies */ info->num_freqs = 0; nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) { @@ -757,6 +758,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) } } + /* Read supported frequencies */ info->freqs = g_malloc0 (sizeof (guint32) * info->num_freqs); freq_idx = 0; @@ -775,10 +777,19 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) info->freqs[freq_idx] = nla_get_u32 (tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + + info->caps |= NM_WIFI_DEVICE_CAP_FREQ_VALID; + + if (info->freqs[freq_idx] > 2400 && info->freqs[freq_idx] < 2500) + info->caps |= NM_WIFI_DEVICE_CAP_FREQ_2GHZ; + if (info->freqs[freq_idx] > 4900 && info->freqs[freq_idx] < 6000) + info->caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ; + freq_idx++; } } + /* Read security/encryption support */ if (tb[NL80211_ATTR_CIPHER_SUITES]) { int num; int i; diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index e0331de7..8428010a 100644 --- a/src/platform/wifi/wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -569,6 +569,7 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; int i; + gboolean freq_valid = FALSE, has_5ghz = FALSE, has_2ghz = FALSE; wext = wifi_data_new (iface, ifindex, sizeof (*wext)); wext->parent.get_mode = wifi_wext_get_mode; @@ -609,8 +610,14 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) wext->max_qual.updated = range.max_qual.updated; wext->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); - for (i = 0; i < wext->num_freqs; i++) + for (i = 0; i < wext->num_freqs; i++) { wext->freqs[i] = iw_freq_to_uint32 (&range.freq[i]); + freq_valid = TRUE; + if (wext->freqs[i] > 2400 && wext->freqs[i] < 2500) + has_2ghz = TRUE; + else if (wext->freqs[i] > 4900 && wext->freqs[i] < 6000) + has_5ghz = TRUE; + } /* Check for scanning capability; cards that can't scan are not supported */ if (check_scan && (wext_can_scan (wext) == FALSE)) { @@ -638,6 +645,12 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) } wext->parent.caps = wext_get_caps (wext, &range); + if (freq_valid) + wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_VALID; + if (has_2ghz) + wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_2GHZ; + if (has_5ghz) + wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ; nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): using WEXT for WiFi device control", diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index f1b57ace..eb37bc22 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -44,7 +44,8 @@ gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); /* Returns frequency in MHz */ guint32 wifi_utils_get_freq (WifiData *data); -/* Return the first supported frequency in the zero-terminated list */ +/* Return the first supported frequency in the zero-terminated list. + * Frequencies are specified in MHz. */ guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); /* Caller must free returned byte array */ diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in index 775e4b5a..ddbb7de0 100644 --- a/src/ppp-manager/Makefile.in +++ b/src/ppp-manager/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/ppp-manager -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -205,6 +214,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -231,7 +242,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -266,6 +276,7 @@ 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@ @@ -503,7 +514,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/ppp-manager/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/ppp-manager/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -573,14 +583,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -802,6 +812,8 @@ uninstall-am: uninstall-pppd_pluginLTLIBRARIES pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pppd_pluginLTLIBRARIES +.PRECIOUS: Makefile + # 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/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 4fac96dc..65993deb 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -68,6 +68,7 @@ static gboolean impl_ppp_manager_set_ip6_config (NMPPPManager *manager, #include "nm-ppp-manager-glue.h" static void _ppp_cleanup (NMPPPManager *manager); +static void _ppp_kill (NMPPPManager *manager); #define NM_PPPD_PLUGIN PPPD_PLUGIN_DIR "/nm-pppd-plugin.so" #define PPP_MANAGER_SECRET_TRIES "ppp-manager-secret-tries" @@ -139,6 +140,7 @@ dispose (GObject *object) NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); _ppp_cleanup (NM_PPP_MANAGER (object)); + _ppp_kill (NM_PPP_MANAGER (object)); g_clear_object (&priv->act_req); @@ -836,6 +838,7 @@ pppd_timed_out (gpointer data) nm_log_warn (LOGD_PPP, "pppd timed out or didn't initialize our dbus module"); _ppp_cleanup (manager); + _ppp_kill (manager); g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_PPP_STATUS_DEAD); @@ -1160,6 +1163,21 @@ out: } static void +_ppp_kill (NMPPPManager *manager) +{ + NMPPPManagerPrivate *priv; + + g_return_if_fail (NM_IS_PPP_MANAGER (manager)); + + priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + + if (priv->pid) { + nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_PPP, "pppd", 2000, NULL, NULL); + priv->pid = 0; + } +} + +static void _ppp_cleanup (NMPPPManager *manager) { NMPPPManagerPrivate *priv; @@ -1191,9 +1209,96 @@ _ppp_cleanup (NMPPPManager *manager) g_source_remove (priv->ppp_watch_id); priv->ppp_watch_id = 0; } +} - if (priv->pid) { - nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_PPP, "pppd", 2000, NULL, NULL); - priv->pid = 0; +/***********************************************************/ + +typedef struct { + NMPPPManager *manager; + GSimpleAsyncResult *result; + GCancellable *cancellable; +} StopContext; + +static void +stop_context_complete (StopContext *ctx) +{ + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->manager); + g_slice_free (StopContext, ctx); +} + +static gboolean +stop_context_complete_if_cancelled (StopContext *ctx) +{ + GError *error = NULL; + + if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + stop_context_complete (ctx); + return TRUE; } + return FALSE; +} + +gboolean +nm_ppp_manager_stop_finish (NMPPPManager *manager, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +kill_child_ready (pid_t pid, + gboolean success, + int child_status, + StopContext *ctx) +{ + if (stop_context_complete_if_cancelled (ctx)) + return; + stop_context_complete (ctx); +} + +void +nm_ppp_manager_stop (NMPPPManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + StopContext *ctx; + + ctx = g_slice_new0 (StopContext); + ctx->manager = g_object_ref (manager); + ctx->result = g_simple_async_result_new (G_OBJECT (manager), + callback, + user_data, + nm_ppp_manager_stop); + + /* Setup cancellable */ + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + if (stop_context_complete_if_cancelled (ctx)) + return; + + /* Cleanup internals */ + _ppp_cleanup (manager); + + /* If no pppd running, we're done */ + if (!priv->pid) { + stop_context_complete (ctx); + return; + } + + /* No cancellable operation, so just wait until it returns always */ + nm_utils_kill_child_async (priv->pid, + SIGTERM, + LOGD_PPP, + "pppd", + 2000, + (NMUtilsKillChildAsyncCb) kill_child_ready, + ctx); + priv->pid = 0; } diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 84be76d0..f8cbda13 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -24,6 +24,7 @@ #include <glib.h> #include <glib-object.h> +#include <gio/gio.h> #include "nm-ppp-status.h" #include "nm-activation-request.h" @@ -69,5 +70,12 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager, guint32 timeout_secs, GError **err); +void nm_ppp_manager_stop (NMPPPManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_ppp_manager_stop_finish (NMPPPManager *manager, + GAsyncResult *res, + GError **error); #endif /* __NETWORKMANAGER_PPP_MANAGER_H__ */ diff --git a/src/rdisc/Makefile.in b/src/rdisc/Makefile.in index 47a71931..349616f7 100644 --- a/src/rdisc/Makefile.in +++ b/src/rdisc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,7 +88,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/rdisc -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -95,6 +104,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -154,6 +164,7 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -205,7 +216,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -240,6 +250,7 @@ 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@ @@ -456,7 +467,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rdisc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/rdisc/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -751,6 +761,8 @@ uninstall-am: mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + # 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/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c index e631f28d..68f43c0e 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/rdisc/nm-fake-rdisc.c @@ -24,6 +24,7 @@ #include <arpa/inet.h> #include "nm-fake-rdisc.h" +#include "nm-rdisc-private.h" #include "nm-logging.h" @@ -31,10 +32,314 @@ #define warning(...) nm_log_warn (LOGD_IP6, __VA_ARGS__) #define error(...) nm_log_err (LOGD_IP6, __VA_ARGS__) +typedef struct { + guint id; + guint when; + + NMRDiscDHCPLevel dhcp_level; + GArray *gateways; + GArray *addresses; + GArray *routes; + GArray *dns_servers; + GArray *dns_domains; + int hop_limit; + guint32 mtu; +} FakeRa; + +typedef struct { + guint receive_ra_id; + GSList *ras; +} NMFakeRDiscPrivate; + #define NM_FAKE_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_FAKE_RDISC, NMFakeRDiscPrivate)) G_DEFINE_TYPE (NMFakeRDisc, nm_fake_rdisc, NM_TYPE_RDISC) +enum { + RS_SENT, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/******************************************************************/ + +static void +fake_ra_free (gpointer data) +{ + FakeRa *ra = data; + + g_array_free (ra->gateways, TRUE); + g_array_free (ra->addresses, TRUE); + g_array_free (ra->routes, TRUE); + g_array_free (ra->dns_servers, TRUE); + g_array_free (ra->dns_domains, TRUE); + g_free (ra); +} + +static void +ra_dns_domain_free (gpointer data) +{ + g_free (((NMRDiscDNSDomain *)(data))->domain); +} + +static FakeRa * +find_ra (GSList *ras, guint id) +{ + GSList *iter; + + for (iter = ras; iter; iter = iter->next) { + if (((FakeRa *) iter->data)->id == id) + return iter->data; + } + return NULL; +} + +guint +nm_fake_rdisc_add_ra (NMFakeRDisc *self, + guint seconds_after_previous, + NMRDiscDHCPLevel dhcp_level, + int hop_limit, + guint32 mtu) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + static guint counter = 1; + FakeRa *ra; + + ra = g_malloc0 (sizeof (*ra)); + ra->id = counter++; + ra->when = seconds_after_previous; + ra->dhcp_level = dhcp_level; + ra->hop_limit = hop_limit; + ra->mtu = mtu; + ra->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway)); + ra->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress)); + ra->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute)); + ra->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); + ra->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); + g_array_set_clear_func (ra->dns_domains, ra_dns_domain_free); + + priv->ras = g_slist_append (priv->ras, ra); + return ra->id; +} + +void +nm_fake_rdisc_add_gateway (NMFakeRDisc *self, + guint ra_id, + const char *addr, + guint32 timestamp, + guint32 lifetime, + NMRDiscPreference preference) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + FakeRa *ra = find_ra (priv->ras, ra_id); + NMRDiscGateway *gw; + + g_assert (ra); + g_array_set_size (ra->gateways, ra->gateways->len + 1); + gw = &g_array_index (ra->gateways, NMRDiscGateway, ra->gateways->len - 1); + g_assert (inet_pton (AF_INET6, addr, &gw->address) == 1); + gw->timestamp = timestamp; + gw->lifetime = lifetime; + gw->preference = preference; +} + +void +nm_fake_rdisc_add_address (NMFakeRDisc *self, + guint ra_id, + const char *addr, + guint32 timestamp, + guint32 lifetime, + guint32 preferred) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + FakeRa *ra = find_ra (priv->ras, ra_id); + NMRDiscAddress *a; + + g_assert (ra); + g_array_set_size (ra->addresses, ra->addresses->len + 1); + a = &g_array_index (ra->addresses, NMRDiscAddress, ra->addresses->len - 1); + g_assert (inet_pton (AF_INET6, addr, &a->address) == 1); + a->timestamp = timestamp; + a->lifetime = lifetime; + a->preferred = preferred; +} + +void +nm_fake_rdisc_add_route (NMFakeRDisc *self, + guint ra_id, + const char *network, + guint plen, + const char *gateway, + guint32 timestamp, + guint32 lifetime, + NMRDiscPreference preference) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + FakeRa *ra = find_ra (priv->ras, ra_id); + NMRDiscRoute *route; + + g_assert (ra); + g_array_set_size (ra->routes, ra->routes->len + 1); + route = &g_array_index (ra->routes, NMRDiscRoute, ra->routes->len - 1); + g_assert (inet_pton (AF_INET6, network, &route->network) == 1); + g_assert (inet_pton (AF_INET6, gateway, &route->gateway) == 1); + route->plen = plen; + route->timestamp = timestamp; + route->lifetime = lifetime; + route->preference = preference; +} + +void +nm_fake_rdisc_add_dns_server (NMFakeRDisc *self, + guint ra_id, + const char *address, + guint32 timestamp, + guint32 lifetime) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + FakeRa *ra = find_ra (priv->ras, ra_id); + NMRDiscDNSServer *dns; + + g_assert (ra); + g_array_set_size (ra->dns_servers, ra->dns_servers->len + 1); + dns = &g_array_index (ra->dns_servers, NMRDiscDNSServer, ra->dns_servers->len - 1); + g_assert (inet_pton (AF_INET6, address, &dns->address) == 1); + dns->timestamp = timestamp; + dns->lifetime = lifetime; +} + +void +nm_fake_rdisc_add_dns_domain (NMFakeRDisc *self, + guint ra_id, + const char *domain, + guint32 timestamp, + guint32 lifetime) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + FakeRa *ra = find_ra (priv->ras, ra_id); + NMRDiscDNSDomain *dns; + + g_assert (ra); + g_array_set_size (ra->dns_domains, ra->dns_domains->len + 1); + dns = &g_array_index (ra->dns_domains, NMRDiscDNSDomain, ra->dns_domains->len - 1); + dns->domain = g_strdup (domain); + dns->timestamp = timestamp; + dns->lifetime = lifetime; +} + +gboolean +nm_fake_rdisc_done (NMFakeRDisc *self) +{ + return !NM_FAKE_RDISC_GET_PRIVATE (self)->ras; +} + +/******************************************************************/ + +static gboolean +send_rs (NMRDisc *rdisc) +{ + g_signal_emit (rdisc, signals[RS_SENT], 0); + return TRUE; +} + +static gboolean +receive_ra (gpointer user_data) +{ + NMFakeRDisc *self = user_data; + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMRDisc *rdisc = NM_RDISC (self); + FakeRa *ra = priv->ras->data; + NMRDiscConfigMap changed = 0; + guint32 now = nm_utils_get_monotonic_timestamp_s (); + guint i; + + priv->receive_ra_id = 0; + + if (rdisc->dhcp_level != ra->dhcp_level) { + rdisc->dhcp_level = ra->dhcp_level; + changed |= NM_RDISC_CONFIG_DHCP_LEVEL; + } + + for (i = 0; i < ra->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (ra->gateways, NMRDiscGateway, i); + + if (nm_rdisc_add_gateway (rdisc, item)) + changed |= NM_RDISC_CONFIG_GATEWAYS; + } + + for (i = 0; i < ra->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (ra->addresses, NMRDiscAddress, i); + + if (nm_rdisc_add_address (rdisc, item)) + changed |= NM_RDISC_CONFIG_ADDRESSES; + } + + for (i = 0; i < ra->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (ra->routes, NMRDiscRoute, i); + + if (nm_rdisc_add_route (rdisc, item)) + changed |= NM_RDISC_CONFIG_ROUTES; + } + + for (i = 0; i < ra->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (ra->dns_servers, NMRDiscDNSServer, i); + + if (nm_rdisc_add_dns_server (rdisc, item)) + changed |= NM_RDISC_CONFIG_DNS_SERVERS; + } + + for (i = 0; i < ra->dns_domains->len; i++) { + NMRDiscDNSDomain *item = &g_array_index (ra->dns_domains, NMRDiscDNSDomain, i); + + if (nm_rdisc_add_dns_domain (rdisc, item)) + changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + } + + if (rdisc->mtu != ra->mtu) { + rdisc->mtu = ra->mtu; + changed |= NM_RDISC_CONFIG_MTU; + } + + if (rdisc->hop_limit != ra->hop_limit) { + rdisc->hop_limit = ra->hop_limit; + changed |= NM_RDISC_CONFIG_HOP_LIMIT; + } + + priv->ras = g_slist_remove (priv->ras, priv->ras->data); + fake_ra_free (ra); + + nm_rdisc_ra_received (NM_RDISC (self), now, changed); + + /* Schedule next RA */ + if (priv->ras) { + ra = priv->ras->data; + priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, self); + } + + return G_SOURCE_REMOVE; +} + +static void +start (NMRDisc *rdisc) +{ + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (rdisc); + FakeRa *ra; + + /* Queue up the first fake RA */ + g_assert (priv->ras); + ra = NM_FAKE_RDISC_GET_PRIVATE (rdisc)->ras->data; + + g_assert (!priv->receive_ra_id); + priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, rdisc); +} + +void +nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self) +{ + if (!NM_FAKE_RDISC_GET_PRIVATE (self)->receive_ra_id) + start (NM_RDISC (self)); +} + /******************************************************************/ NMRDisc * @@ -52,85 +357,42 @@ nm_fake_rdisc_new (int ifindex, const char *ifname) } static void -delayed_start (NMRDisc *rdisc) +nm_fake_rdisc_init (NMFakeRDisc *fake_rdisc) { - int changed = - NM_RDISC_CONFIG_GATEWAYS | NM_RDISC_CONFIG_ADDRESSES | NM_RDISC_CONFIG_ROUTES | - NM_RDISC_CONFIG_DNS_SERVERS | NM_RDISC_CONFIG_DNS_DOMAINS; - debug ("%d", rdisc->dhcp_level); - - g_signal_emit_by_name ( - rdisc, NM_RDISC_CONFIG_CHANGED, changed); } static void -start (NMRDisc *rdisc) +dispose (GObject *object) { - g_idle_add ((GSourceFunc) (delayed_start), rdisc); -} + NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (object); -/******************************************************************/ + if (priv->receive_ra_id) { + g_source_remove (priv->receive_ra_id); + priv->receive_ra_id = 0; + } -static void -nm_fake_rdisc_init (NMFakeRDisc *fake_rdisc) -{ - NMRDisc *rdisc = NM_RDISC (fake_rdisc); - NMRDiscGateway gateway; - NMRDiscAddress address; - NMRDiscRoute route; - NMRDiscDNSServer dns_server; - NMRDiscDNSDomain dns_domain; - - rdisc->dhcp_level = NM_RDISC_DHCP_LEVEL_NONE; - - memset (&gateway, 0, sizeof (gateway)); - inet_pton (AF_INET6, "fe80::1", &gateway.address); - g_array_append_val (rdisc->gateways, gateway); - inet_pton (AF_INET6, "fe80::2", &gateway.address); - g_array_append_val (rdisc->gateways, gateway); - inet_pton (AF_INET6, "fe80::3", &gateway.address); - g_array_append_val (rdisc->gateways, gateway); - - memset (&address, 0, sizeof (address)); - inet_pton (AF_INET6, "2001:db8:a:a::1", &address.address); - g_array_append_val (rdisc->addresses, address); - inet_pton (AF_INET6, "2001:db8:a:a::2", &address.address); - g_array_append_val (rdisc->addresses, address); - inet_pton (AF_INET6, "2001:db8:f:f::1", &address.address); - g_array_append_val (rdisc->addresses, address); - - memset (&route, 0, sizeof (route)); - route.plen = 64; - inet_pton (AF_INET6, "2001:db8:a:a::", &route.network); - g_array_append_val (rdisc->routes, route); - inet_pton (AF_INET6, "2001:db8:b:b::", &route.network); - g_array_append_val (rdisc->routes, route); - - memset (&dns_server, 0, sizeof (dns_server)); - inet_pton (AF_INET6, "2001:db8:c:c::1", &dns_server.address); - g_array_append_val (rdisc->dns_servers, dns_server); - inet_pton (AF_INET6, "2001:db8:c:c::2", &dns_server.address); - g_array_append_val (rdisc->dns_servers, dns_server); - inet_pton (AF_INET6, "2001:db8:c:c::3", &dns_server.address); - g_array_append_val (rdisc->dns_servers, dns_server); - inet_pton (AF_INET6, "2001:db8:c:c::4", &dns_server.address); - g_array_append_val (rdisc->dns_servers, dns_server); - inet_pton (AF_INET6, "2001:db8:c:c::5", &dns_server.address); - g_array_append_val (rdisc->dns_servers, dns_server); - - memset (&dns_domain, 0, sizeof (dns_domain)); - dns_domain.domain = g_strdup ("example.net"); - g_array_append_val (rdisc->dns_domains, dns_domain); - dns_domain.domain = g_strdup ("example.com"); - g_array_append_val (rdisc->dns_domains, dns_domain); - dns_domain.domain = g_strdup ("example.org"); - g_array_append_val (rdisc->dns_domains, dns_domain); + g_slist_free_full (priv->ras, fake_ra_free); + priv->ras = NULL; + + G_OBJECT_CLASS (nm_fake_rdisc_parent_class)->dispose (object); } static void nm_fake_rdisc_class_init (NMFakeRDiscClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); NMRDiscClass *rdisc_class = NM_RDISC_CLASS (klass); + g_type_class_add_private (klass, sizeof (NMFakeRDiscPrivate)); + + object_class->dispose = dispose; rdisc_class->start = start; + rdisc_class->send_rs = send_rs; + + signals[RS_SENT] = g_signal_new ( + NM_FAKE_RDISC_RS_SENT, + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); } diff --git a/src/rdisc/nm-fake-rdisc.h b/src/rdisc/nm-fake-rdisc.h index b4eff7ec..74f74897 100644 --- a/src/rdisc/nm-fake-rdisc.h +++ b/src/rdisc/nm-fake-rdisc.h @@ -30,7 +30,7 @@ #define NM_IS_FAKE_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FAKE_RDISC)) #define NM_FAKE_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FAKE_RDISC, NMFakeRDiscClass)) -/******************************************************************/ +#define NM_FAKE_RDISC_RS_SENT "rs-sent" typedef struct { NMRDisc parent; @@ -46,4 +46,49 @@ GType nm_fake_rdisc_get_type (void); NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname); +guint nm_fake_rdisc_add_ra (NMFakeRDisc *self, + guint seconds, + NMRDiscDHCPLevel dhcp_level, + int hop_limit, + guint32 mtu); + +void nm_fake_rdisc_add_gateway (NMFakeRDisc *self, + guint ra_id, + const char *addr, + guint32 timestamp, + guint32 lifetime, + NMRDiscPreference preference); + +void nm_fake_rdisc_add_address (NMFakeRDisc *self, + guint ra_id, + const char *addr, + guint32 timestamp, + guint32 lifetime, + guint32 preferred); + +void nm_fake_rdisc_add_route (NMFakeRDisc *self, + guint ra_id, + const char *network, + guint plen, + const char *gateway, + guint32 timestamp, + guint32 lifetime, + NMRDiscPreference preference); + +void nm_fake_rdisc_add_dns_server (NMFakeRDisc *self, + guint ra_id, + const char *address, + guint32 timestamp, + guint32 lifetime); + +void nm_fake_rdisc_add_dns_domain (NMFakeRDisc *self, + guint ra_id, + const char *domain, + guint32 timestamp, + guint32 lifetime); + +void nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self); + +gboolean nm_fake_rdisc_done (NMFakeRDisc *self); + #endif /* __NETWORKMANAGER_FAKE_RDISC_H__ */ diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index ff1bd33d..cadbfdfa 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -27,6 +27,7 @@ #include <ndp.h> #include "nm-lndp-rdisc.h" +#include "nm-rdisc-private.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" @@ -39,13 +40,9 @@ typedef struct { struct ndp *ndp; - guint send_rs_id; GIOChannel *event_channel; guint event_id; - guint timeout_id; /* prefix/dns/etc lifetime timeout */ guint ra_timeout_id; /* first RA timeout */ - - int solicitations_left; } NMLNDPRDiscPrivate; #define NM_LNDP_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LNDP_RDISC, NMLNDPRDiscPrivate)) @@ -54,185 +51,6 @@ G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) /******************************************************************/ -static inline gint32 -ipv6_sysctl_get (const char *ifname, const char *property, gint32 defval) -{ - return nm_platform_sysctl_get_int32 (nm_utils_ip6_property_path (ifname, property), defval); -} - -NMRDisc * -nm_lndp_rdisc_new (int ifindex, const char *ifname) -{ - NMRDisc *rdisc; - NMLNDPRDiscPrivate *priv; - int error; - - rdisc = g_object_new (NM_TYPE_LNDP_RDISC, NULL); - - rdisc->ifindex = ifindex; - rdisc->ifname = g_strdup (ifname); - - rdisc->max_addresses = ipv6_sysctl_get (ifname, "max_addresses", - NM_RDISC_MAX_ADDRESSES_DEFAULT); - rdisc->rtr_solicitations = ipv6_sysctl_get (ifname, "router_solicitations", - NM_RDISC_RTR_SOLICITATIONS_DEFAULT); - rdisc->rtr_solicitation_interval = ipv6_sysctl_get (ifname, "router_solicitation_interval", - NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT); - - priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - error = ndp_open (&priv->ndp); - if (error != 0) { - g_object_unref (rdisc); - debug ("(%s): error creating socket for NDP; errno=%d", ifname, -error); - return NULL; - } - return rdisc; -} - -static gboolean -add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) -{ - int i; - - for (i = 0; i < rdisc->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); - - if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { - if (item->preference != new->preference) { - g_array_remove_index (rdisc->gateways, i--); - continue; - } - memcpy (item, new, sizeof (*new)); - return FALSE; - } - - /* Put before less preferable gateways. */ - if (item->preference < new->preference) - break; - } - - g_array_insert_val (rdisc->gateways, i, *new); - return TRUE; -} - -static gboolean -add_address (NMRDisc *rdisc, const NMRDiscAddress *new) -{ - int i; - - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); - - if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { - gboolean changed = item->timestamp + item->lifetime != new->timestamp + new->lifetime || - item->timestamp + item->preferred != new->timestamp + new->preferred; - - *item = *new; - return changed; - } - } - - /* we create at most max_addresses autoconf addresses. This is different from - * what the kernel does, because it considers *all* addresses (including - * static and other temporary addresses). - **/ - if (rdisc->max_addresses && rdisc->addresses->len >= rdisc->max_addresses) - return FALSE; - - g_array_insert_val (rdisc->addresses, i, *new); - return TRUE; -} - -static gboolean -add_route (NMRDisc *rdisc, const NMRDiscRoute *new) -{ - int i; - - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); - - if (IN6_ARE_ADDR_EQUAL (&item->network, &new->network) && item->plen == new->plen) { - if (item->preference != new->preference) { - g_array_remove_index (rdisc->routes, i--); - continue; - } - memcpy (item, new, sizeof (*new)); - return FALSE; - } - - /* Put before less preferable routes. */ - if (item->preference < new->preference) - break; - } - - g_array_insert_val (rdisc->routes, i, *new); - return TRUE; -} - -static gboolean -add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) -{ - int i; - - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); - - if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { - gboolean changed; - - if (new->lifetime == 0) { - g_array_remove_index (rdisc->dns_servers, i); - return TRUE; - } - - changed = (item->timestamp != new->timestamp || - item->lifetime != new->lifetime); - if (changed) { - item->timestamp = new->timestamp; - item->lifetime = new->lifetime; - } - return changed; - } - } - - g_array_insert_val (rdisc->dns_servers, i, *new); - return TRUE; -} - -/* Copies new->domain if 'new' is added to the dns_domains list */ -static gboolean -add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) -{ - NMRDiscDNSDomain *item; - int i; - - for (i = 0; i < rdisc->dns_domains->len; i++) { - item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); - - if (!g_strcmp0 (item->domain, new->domain)) { - gboolean changed; - - if (new->lifetime == 0) { - g_array_remove_index (rdisc->dns_domains, i); - return TRUE; - } - - changed = (item->timestamp != new->timestamp || - item->lifetime != new->lifetime); - if (changed) { - item->timestamp = new->timestamp; - item->lifetime = new->lifetime; - } - return changed; - } - } - - g_array_insert_val (rdisc->dns_domains, i, *new); - item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); - item->domain = g_strdup (new->domain); - return TRUE; -} - static gboolean send_rs (NMRDisc *rdisc) { @@ -244,185 +62,12 @@ send_rs (NMRDisc *rdisc) g_assert (!error); ndp_msg_ifindex_set (msg, rdisc->ifindex); - debug ("(%s): sending router solicitation", rdisc->ifname); - error = ndp_msg_send (priv->ndp, msg); - if (error) - error ("(%s): cannot send router solicitation: %d.", rdisc->ifname, error); - else - priv->solicitations_left--; - ndp_msg_destroy (msg); - - if (priv->solicitations_left > 0) { - debug ("(%s): scheduling router solicitation retry in %d seconds.", - rdisc->ifname, rdisc->rtr_solicitation_interval); - priv->send_rs_id = g_timeout_add_seconds (rdisc->rtr_solicitation_interval, - (GSourceFunc) send_rs, rdisc); - } else { - debug ("(%s): did not receive a router advertisement after %d solicitations.", - rdisc->ifname, rdisc->rtr_solicitations); - priv->send_rs_id = 0; - } - - return G_SOURCE_REMOVE; -} - -static void -solicit (NMRDisc *rdisc) -{ - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - - if (!priv->send_rs_id) { - debug ("(%s): scheduling router solicitation.", rdisc->ifname); - priv->send_rs_id = g_idle_add ((GSourceFunc) send_rs, rdisc); - priv->solicitations_left = rdisc->rtr_solicitations; - } -} - -static void -clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) -{ - int i; - - for (i = 0; i < rdisc->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); - guint64 expiry = (guint64) item->timestamp + item->lifetime; - - if (item->lifetime == G_MAXUINT32) - continue; - - if (now >= expiry) { - g_array_remove_index (rdisc->gateways, i--); - *changed |= NM_RDISC_CONFIG_GATEWAYS; - } else if (*nextevent > expiry) - *nextevent = expiry; - } -} - -static void -clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) -{ - int i; - - for (i = 0; i < rdisc->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); - guint64 expiry = (guint64) item->timestamp + item->lifetime; - - if (item->lifetime == G_MAXUINT32) - continue; - - if (now >= expiry) { - g_array_remove_index (rdisc->addresses, i--); - *changed |= NM_RDISC_CONFIG_ADDRESSES; - } else if (*nextevent > expiry) - *nextevent = expiry; - } -} - -static void -clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) -{ - int i; - - for (i = 0; i < rdisc->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); - guint64 expiry = (guint64) item->timestamp + item->lifetime; - - if (item->lifetime == G_MAXUINT32) - continue; - - if (now >= expiry) { - g_array_remove_index (rdisc->routes, i--); - *changed |= NM_RDISC_CONFIG_ROUTES; - } else if (*nextevent > expiry) - *nextevent = expiry; - } -} - -static void -clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) -{ - int i; - - for (i = 0; i < rdisc->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); - guint64 expiry = (guint64) item->timestamp + item->lifetime; - guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; - - if (item->lifetime == G_MAXUINT32) - continue; - - if (now >= expiry) { - g_array_remove_index (rdisc->dns_servers, i--); - *changed |= NM_RDISC_CONFIG_DNS_SERVERS; - } else if (now >= refresh) - solicit (rdisc); - else if (*nextevent > refresh) - *nextevent = refresh; - } -} - -static void -clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) -{ - int i; - - for (i = 0; i < rdisc->dns_domains->len; i++) { - NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); - guint64 expiry = (guint64) item->timestamp + item->lifetime; - guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; - - if (item->lifetime == G_MAXUINT32) - continue; - - if (now >= expiry) { - g_free (item->domain); - g_array_remove_index (rdisc->dns_domains, i--); - *changed |= NM_RDISC_CONFIG_DNS_DOMAINS; - } else if (now >= refresh) - solicit (rdisc); - else if (*nextevent > refresh) - *nextevent = refresh; - } -} - -static gboolean timeout_cb (gpointer user_data); - -static void -check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) -{ - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - /* Use a magic date in the distant future (~68 years) */ - guint32 never = G_MAXINT32; - guint32 nextevent = never; - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - clean_gateways (rdisc, now, &changed, &nextevent); - clean_addresses (rdisc, now, &changed, &nextevent); - clean_routes (rdisc, now, &changed, &nextevent); - clean_dns_servers (rdisc, now, &changed, &nextevent); - clean_dns_domains (rdisc, now, &changed, &nextevent); - - if (changed) - g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, changed); - - if (nextevent != never) { - g_return_if_fail (nextevent > now); - debug ("(%s): scheduling next now/lifetime check: %u seconds", - rdisc->ifname, nextevent - now); - priv->timeout_id = g_timeout_add_seconds (nextevent - now, timeout_cb, rdisc); + if (error) { + error ("(%s): cannot send router solicitation: %d.", rdisc->ifname, error); + return FALSE; } -} - -static gboolean -timeout_cb (gpointer user_data) -{ - check_timestamps (user_data, nm_utils_get_monotonic_timestamp_s (), 0); return TRUE; } @@ -442,28 +87,6 @@ translate_preference (enum ndp_route_preference preference) } } -static void -clear_rs_timeout (NMLNDPRDisc *rdisc) -{ - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - - if (priv->send_rs_id) { - g_source_remove (priv->send_rs_id); - priv->send_rs_id = 0; - } -} - -static void -clear_ra_timeout (NMLNDPRDisc *rdisc) -{ - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - - if (priv->ra_timeout_id) { - g_source_remove (priv->ra_timeout_id); - priv->ra_timeout_id = 0; - } -} - static int receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) { @@ -488,9 +111,6 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ debug ("(%s): received router advertisement at %u", rdisc->ifname, now); - clear_ra_timeout (NM_LNDP_RDISC (rdisc)); - clear_rs_timeout (NM_LNDP_RDISC (rdisc)); - /* DHCP level: * * The problem with DHCP level is what to do if subsequent @@ -524,7 +144,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) gateway.timestamp = now; gateway.lifetime = ndp_msgra_router_lifetime (msgra); gateway.preference = translate_preference (ndp_msgra_route_preference (msgra)); - if (add_gateway (rdisc, &gateway)) + if (nm_rdisc_add_gateway (rdisc, &gateway)) changed |= NM_RDISC_CONFIG_GATEWAYS; /* Addresses & Routes */ @@ -539,7 +159,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) route.timestamp = now; if (ndp_msg_opt_prefix_flag_on_link (msg, offset)) { route.lifetime = ndp_msg_opt_prefix_valid_time (msg, offset); - if (add_route (rdisc, &route)) + if (nm_rdisc_add_route (rdisc, &route)) changed |= NM_RDISC_CONFIG_ROUTES; } @@ -557,7 +177,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) /* Add the Interface Identifier to the lower 64 bits */ nm_utils_ipv6_addr_set_interface_identfier (&address.address, rdisc->iid); - if (add_address (rdisc, &address)) + if (nm_rdisc_add_address (rdisc, &address)) changed |= NM_RDISC_CONFIG_ADDRESSES; } } @@ -573,7 +193,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) route.timestamp = now; route.lifetime = ndp_msg_opt_route_lifetime (msg, offset); route.preference = translate_preference (ndp_msg_opt_route_preference (msg, offset)); - if (add_route (rdisc, &route)) + if (nm_rdisc_add_route (rdisc, &route)) changed |= NM_RDISC_CONFIG_ROUTES; } @@ -596,7 +216,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ if (dns_server.lifetime && dns_server.lifetime < 7200) dns_server.lifetime = 7200; - if (add_dns_server (rdisc, &dns_server)) + if (nm_rdisc_add_dns_server (rdisc, &dns_server)) changed |= NM_RDISC_CONFIG_DNS_SERVERS; } } @@ -618,7 +238,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ if (dns_domain.lifetime && dns_domain.lifetime < 7200) dns_domain.lifetime = 7200; - if (add_dns_domain (rdisc, &dns_domain)) + if (nm_rdisc_add_dns_domain (rdisc, &dns_domain)) changed |= NM_RDISC_CONFIG_DNS_DOMAINS; } } @@ -644,8 +264,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) } } - check_timestamps (rdisc, now, changed); - + nm_rdisc_ra_received (rdisc, now, changed); return 0; } @@ -659,41 +278,58 @@ event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) return G_SOURCE_CONTINUE; } -static gboolean -rdisc_ra_timeout_cb (gpointer user_data) -{ - NMLNDPRDisc *rdisc = NM_LNDP_RDISC (user_data); - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - - priv->ra_timeout_id = 0; - g_signal_emit_by_name (rdisc, NM_RDISC_RA_TIMEOUT); - return G_SOURCE_REMOVE; -} - static void start (NMRDisc *rdisc) { NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); int fd = ndp_get_eventfd (priv->ndp); - guint ra_wait_secs; priv->event_channel = g_io_channel_unix_new (fd); priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, rdisc); - clear_ra_timeout (NM_LNDP_RDISC (rdisc)); - ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120); - priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc); - debug ("(%s): scheduling RA timeout in %d seconds", rdisc->ifname, ra_wait_secs); - /* Flush any pending messages to avoid using obsolete information */ event_ready (priv->event_channel, 0, rdisc); ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, rdisc->ifindex, rdisc); - solicit (rdisc); } /******************************************************************/ +static inline gint32 +ipv6_sysctl_get (const char *ifname, const char *property, gint32 defval) +{ + return nm_platform_sysctl_get_int32 (nm_utils_ip6_property_path (ifname, property), defval); +} + +NMRDisc * +nm_lndp_rdisc_new (int ifindex, const char *ifname) +{ + NMRDisc *rdisc; + NMLNDPRDiscPrivate *priv; + int error; + + rdisc = g_object_new (NM_TYPE_LNDP_RDISC, NULL); + + rdisc->ifindex = ifindex; + rdisc->ifname = g_strdup (ifname); + + rdisc->max_addresses = ipv6_sysctl_get (ifname, "max_addresses", + NM_RDISC_MAX_ADDRESSES_DEFAULT); + rdisc->rtr_solicitations = ipv6_sysctl_get (ifname, "router_solicitations", + NM_RDISC_RTR_SOLICITATIONS_DEFAULT); + rdisc->rtr_solicitation_interval = ipv6_sysctl_get (ifname, "router_solicitation_interval", + NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT); + + priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + error = ndp_open (&priv->ndp); + if (error != 0) { + g_object_unref (rdisc); + debug ("(%s): error creating socket for NDP; errno=%d", ifname, -error); + return NULL; + } + return rdisc; +} + static void nm_lndp_rdisc_init (NMLNDPRDisc *lndp_rdisc) { @@ -705,14 +341,6 @@ dispose (GObject *object) NMLNDPRDisc *rdisc = NM_LNDP_RDISC (object); NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - clear_rs_timeout (rdisc); - clear_ra_timeout (rdisc); - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - if (priv->event_id) { g_source_remove (priv->event_id); priv->event_id = 0; @@ -720,9 +348,12 @@ dispose (GObject *object) g_clear_pointer (&priv->event_channel, g_io_channel_unref); if (priv->ndp) { + ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, NM_RDISC (rdisc)->ifindex, rdisc); ndp_close (priv->ndp); priv->ndp = NULL; } + + G_OBJECT_CLASS (nm_lndp_rdisc_parent_class)->dispose (object); } static void @@ -735,4 +366,5 @@ nm_lndp_rdisc_class_init (NMLNDPRDiscClass *klass) object_class->dispose = dispose; rdisc_class->start = start; + rdisc_class->send_rs = send_rs; } diff --git a/src/rdisc/nm-rdisc-private.h b/src/rdisc/nm-rdisc-private.h new file mode 100644 index 00000000..f95949de --- /dev/null +++ b/src/rdisc/nm-rdisc-private.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* nm-rdisc.h - Perform IPv6 router discovery + * + * 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, 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 2015 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_RDISC_PRIVATE_H__ +#define __NETWORKMANAGER_RDISC_PRIVATE_H__ + +#include "nm-rdisc.h" + +/* Functions only used by rdisc implementations */ + +void nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed); + +gboolean nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new); +gboolean nm_rdisc_add_address (NMRDisc *rdisc, const NMRDiscAddress *new); +gboolean nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new); +gboolean nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new); +gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new); + +#endif /* __NETWORKMANAGER_RDISC_PRIVATE_H__ */ diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index 8729fa63..07271a89 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -22,14 +22,26 @@ #include <stdlib.h> #include <arpa/inet.h> +#include <string.h> #include "nm-rdisc.h" +#include "nm-rdisc-private.h" #include "nm-logging.h" #include "nm-utils.h" #define debug(...) nm_log_dbg (LOGD_IP6, __VA_ARGS__) +typedef struct { + int solicitations_left; + guint send_rs_id; + gint64 last_rs; + guint ra_timeout_id; /* first RA timeout */ + guint timeout_id; /* prefix/dns/etc lifetime timeout */ +} NMRDiscPrivate; + +#define NM_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_RDISC, NMRDiscPrivate)) + G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT) enum { @@ -42,6 +54,193 @@ static guint signals[LAST_SIGNAL] = { 0 }; /******************************************************************/ +gboolean +nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) +{ + int i, insert_idx = -1; + + for (i = 0; i < rdisc->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); + + if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { + if (new->lifetime == 0) { + g_array_remove_index (rdisc->gateways, i--); + return TRUE; + } + + if (item->preference != new->preference) { + g_array_remove_index (rdisc->gateways, i--); + continue; + } + + memcpy (item, new, sizeof (*new)); + return FALSE; + } + + /* Put before less preferable gateways. */ + if (item->preference < new->preference && insert_idx < 0) + insert_idx = i; + } + + if (new->lifetime) + g_array_insert_val (rdisc->gateways, CLAMP (insert_idx, 0, G_MAXINT), *new); + return !!new->lifetime; +} + +gboolean +nm_rdisc_add_address (NMRDisc *rdisc, const NMRDiscAddress *new) +{ + int i; + + for (i = 0; i < rdisc->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + + if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { + gboolean changed; + + if (new->lifetime == 0) { + g_array_remove_index (rdisc->addresses, i--); + return TRUE; + } + + changed = item->timestamp + item->lifetime != new->timestamp + new->lifetime || + item->timestamp + item->preferred != new->timestamp + new->preferred; + *item = *new; + return changed; + } + } + + /* we create at most max_addresses autoconf addresses. This is different from + * what the kernel does, because it considers *all* addresses (including + * static and other temporary addresses). + **/ + if (rdisc->max_addresses && rdisc->addresses->len >= rdisc->max_addresses) + return FALSE; + + if (new->lifetime) + g_array_insert_val (rdisc->addresses, i, *new); + return !!new->lifetime; +} + +gboolean +nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new) +{ + int i, insert_idx = -1; + + for (i = 0; i < rdisc->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); + + if (IN6_ARE_ADDR_EQUAL (&item->network, &new->network) && item->plen == new->plen) { + if (new->lifetime == 0) { + g_array_remove_index (rdisc->routes, i--); + return TRUE; + } + + if (item->preference != new->preference) { + g_array_remove_index (rdisc->routes, i--); + continue; + } + + memcpy (item, new, sizeof (*new)); + return FALSE; + } + + /* Put before less preferable routes. */ + if (item->preference < new->preference && insert_idx < 0) + insert_idx = i; + } + + if (new->lifetime) + g_array_insert_val (rdisc->routes, CLAMP (insert_idx, 0, G_MAXINT), *new); + return !!new->lifetime; +} + +gboolean +nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) +{ + int i; + + for (i = 0; i < rdisc->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + + if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { + if (new->lifetime == 0) { + g_array_remove_index (rdisc->dns_servers, i); + return TRUE; + } + if (item->timestamp != new->timestamp || item->lifetime != new->lifetime) { + *item = *new; + return TRUE; + } + return FALSE; + } + } + + if (new->lifetime) + g_array_insert_val (rdisc->dns_servers, i, *new); + return !!new->lifetime; +} + +/* Copies new->domain if 'new' is added to the dns_domains list */ +gboolean +nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) +{ + NMRDiscDNSDomain *item; + int i; + + for (i = 0; i < rdisc->dns_domains->len; i++) { + item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + + if (!g_strcmp0 (item->domain, new->domain)) { + gboolean changed; + + if (new->lifetime == 0) { + g_array_remove_index (rdisc->dns_domains, i); + return TRUE; + } + + changed = (item->timestamp != new->timestamp || + item->lifetime != new->lifetime); + if (changed) { + item->timestamp = new->timestamp; + item->lifetime = new->lifetime; + } + return changed; + } + } + + if (new->lifetime) { + g_array_insert_val (rdisc->dns_domains, i, *new); + item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + item->domain = g_strdup (new->domain); + } + return !!new->lifetime; +} + +/******************************************************************/ + +static void +clear_ra_timeout (NMRDisc *rdisc) +{ + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + + if (priv->ra_timeout_id) { + g_source_remove (priv->ra_timeout_id); + priv->ra_timeout_id = 0; + } +} + +static void +clear_rs_timeout (NMRDisc *rdisc) +{ + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + + if (priv->send_rs_id) { + g_source_remove (priv->send_rs_id); + priv->send_rs_id = 0; + } +} + void nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) { @@ -50,17 +249,79 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) rdisc->iid = iid; } +static gboolean +send_rs (NMRDisc *rdisc) +{ + NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + + debug ("(%s): sending router solicitation", rdisc->ifname); + + if (klass->send_rs (rdisc)) + priv->solicitations_left--; + + priv->last_rs = nm_utils_get_monotonic_timestamp_s (); + if (priv->solicitations_left > 0) { + debug ("(%s): scheduling router solicitation retry in %d seconds.", + rdisc->ifname, rdisc->rtr_solicitation_interval); + priv->send_rs_id = g_timeout_add_seconds (rdisc->rtr_solicitation_interval, + (GSourceFunc) send_rs, rdisc); + } else { + debug ("(%s): did not receive a router advertisement after %d solicitations.", + rdisc->ifname, rdisc->rtr_solicitations); + priv->send_rs_id = 0; + } + + return G_SOURCE_REMOVE; +} + +static void +solicit (NMRDisc *rdisc) +{ + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + gint64 next; + + if (!priv->send_rs_id) { + priv->solicitations_left = rdisc->rtr_solicitations; + + next = CLAMP (priv->last_rs + rdisc->rtr_solicitation_interval - now, 0, G_MAXINT32); + debug ("(%s): scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.", + rdisc->ifname, next); + priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs, rdisc); + } +} + +static gboolean +rdisc_ra_timeout_cb (gpointer user_data) +{ + NMRDisc *rdisc = NM_RDISC (user_data); + + NM_RDISC_GET_PRIVATE (rdisc)->ra_timeout_id = 0; + g_signal_emit_by_name (rdisc, NM_RDISC_RA_TIMEOUT); + return G_SOURCE_REMOVE; +} + void nm_rdisc_start (NMRDisc *rdisc) { + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); + guint ra_wait_secs; g_assert (klass->start); debug ("(%s): starting router discovery: %d", rdisc->ifname, rdisc->ifindex); + clear_ra_timeout (rdisc); + ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120); + priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc); + debug ("(%s): scheduling RA timeout in %d seconds", rdisc->ifname, ra_wait_secs); + if (klass->start) klass->start (rdisc); + + solicit (rdisc); } #define CONFIG_MAP_MAX_STR 7 @@ -145,21 +406,206 @@ config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed) } } +static void +clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +{ + int i; + + for (i = 0; i < rdisc->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); + guint64 expiry = (guint64) item->timestamp + item->lifetime; + + if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->gateways, i--); + *changed |= NM_RDISC_CONFIG_GATEWAYS; + } else if (*nextevent > expiry) + *nextevent = expiry; + } +} + +static void +clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +{ + int i; + + for (i = 0; i < rdisc->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + guint64 expiry = (guint64) item->timestamp + item->lifetime; + + if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->addresses, i--); + *changed |= NM_RDISC_CONFIG_ADDRESSES; + } else if (*nextevent > expiry) + *nextevent = expiry; + } +} + +static void +clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +{ + int i; + + for (i = 0; i < rdisc->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); + guint64 expiry = (guint64) item->timestamp + item->lifetime; + + if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->routes, i--); + *changed |= NM_RDISC_CONFIG_ROUTES; + } else if (*nextevent > expiry) + *nextevent = expiry; + } +} + +static void +clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +{ + int i; + + for (i = 0; i < rdisc->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + guint64 expiry = (guint64) item->timestamp + item->lifetime; + guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; + + if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->dns_servers, i--); + *changed |= NM_RDISC_CONFIG_DNS_SERVERS; + } else if (now >= refresh) + solicit (rdisc); + else if (*nextevent > refresh) + *nextevent = refresh; + } +} + +static void +clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +{ + int i; + + for (i = 0; i < rdisc->dns_domains->len; i++) { + NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + guint64 expiry = (guint64) item->timestamp + item->lifetime; + guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; + + if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->dns_domains, i--); + *changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + } else if (now >= refresh) + solicit (rdisc); + else if (*nextevent > refresh) + *nextevent = refresh; + } +} + +static gboolean timeout_cb (gpointer user_data); + +static void +check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) +{ + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + /* Use a magic date in the distant future (~68 years) */ + guint32 never = G_MAXINT32; + guint32 nextevent = never; + + if (priv->timeout_id) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + + clean_gateways (rdisc, now, &changed, &nextevent); + clean_addresses (rdisc, now, &changed, &nextevent); + clean_routes (rdisc, now, &changed, &nextevent); + clean_dns_servers (rdisc, now, &changed, &nextevent); + clean_dns_domains (rdisc, now, &changed, &nextevent); + + if (changed) + g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, changed); + + if (nextevent != never) { + g_return_if_fail (nextevent > now); + debug ("(%s): scheduling next now/lifetime check: %u seconds", + rdisc->ifname, nextevent - now); + priv->timeout_id = g_timeout_add_seconds (nextevent - now, timeout_cb, rdisc); + } +} + +static gboolean +timeout_cb (gpointer user_data) +{ + NM_RDISC_GET_PRIVATE (user_data)->timeout_id = 0; + check_timestamps (NM_RDISC (user_data), nm_utils_get_monotonic_timestamp_s (), 0); + return G_SOURCE_REMOVE; +} + +void +nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) +{ + clear_ra_timeout (rdisc); + clear_rs_timeout (rdisc); + check_timestamps (rdisc, now, changed); +} + /******************************************************************/ static void +dns_domain_free (gpointer data) +{ + g_free (((NMRDiscDNSDomain *)(data))->domain); +} + +static void nm_rdisc_init (NMRDisc *rdisc) { + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + rdisc->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway)); rdisc->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress)); rdisc->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute)); rdisc->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); rdisc->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); + g_array_set_clear_func (rdisc->dns_domains, dns_domain_free); rdisc->hop_limit = 64; + + /* Start at very low number so that last_rs - rtr_solicitation_interval + * is much lower than nm_utils_get_monotonic_timestamp_s() at startup. + */ + priv->last_rs = G_MININT32; } static void -nm_rdisc_finalize (GObject *object) +dispose (GObject *object) +{ + NMRDisc *rdisc = NM_RDISC (object); + NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + + clear_ra_timeout (rdisc); + clear_rs_timeout (rdisc); + + if (priv->timeout_id) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + + G_OBJECT_CLASS (nm_rdisc_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) { NMRDisc *rdisc = NM_RDISC (object); @@ -169,6 +615,8 @@ nm_rdisc_finalize (GObject *object) g_array_unref (rdisc->routes); g_array_unref (rdisc->dns_servers); g_array_unref (rdisc->dns_domains); + + G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object); } static void @@ -176,8 +624,10 @@ nm_rdisc_class_init (NMRDiscClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = nm_rdisc_finalize; + g_type_class_add_private (klass, sizeof (NMRDiscPrivate)); + object_class->dispose = dispose; + object_class->finalize = finalize; klass->config_changed = config_changed; signals[CONFIG_CHANGED] = g_signal_new ( diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index 2d83f0f0..a79e6c96 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -133,7 +133,9 @@ typedef struct { GObjectClass parent; void (*start) (NMRDisc *rdisc); + gboolean (*send_rs) (NMRDisc *rdisc); void (*config_changed) (NMRDisc *rdisc, NMRDiscConfigMap changed); + void (*ra_process) (NMRDisc *rdisc); void (*ra_timeout) (NMRDisc *rdisc); } NMRDiscClass; diff --git a/src/rdisc/tests/Makefile.am b/src/rdisc/tests/Makefile.am index e6fe1369..5d6f8b5b 100644 --- a/src/rdisc/tests/Makefile.am +++ b/src/rdisc/tests/Makefile.am @@ -20,11 +20,18 @@ AM_LDFLAGS = \ @GNOME_CODE_COVERAGE_RULES@ -noinst_PROGRAMS = \ - rdisc +noinst_PROGRAMS = test-rdisc-linux test-rdisc-fake -rdisc_SOURCES = \ - rdisc.c -rdisc_LDADD = \ +test_rdisc_linux_SOURCES = \ + test-rdisc-linux.c +test_rdisc_linux_LDADD = \ $(top_builddir)/src/libNetworkManager.la +test_rdisc_fake_SOURCES = \ + test-rdisc-fake.c +test_rdisc_fake_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +@VALGRIND_RULES@ +TESTS = test-rdisc-fake + diff --git a/src/rdisc/tests/Makefile.in b/src/rdisc/tests/Makefile.in index b2ea3c74..f241fcbf 100644 --- a/src/rdisc/tests/Makefile.in +++ b/src/rdisc/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,10 +88,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -noinst_PROGRAMS = rdisc$(EXEEXT) +noinst_PROGRAMS = test-rdisc-linux$(EXEEXT) test-rdisc-fake$(EXEEXT) +TESTS = test-rdisc-fake$(EXEEXT) subdir = src/rdisc/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -98,18 +107,24 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am_rdisc_OBJECTS = rdisc.$(OBJEXT) -rdisc_OBJECTS = $(am_rdisc_OBJECTS) -rdisc_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +am_test_rdisc_fake_OBJECTS = test-rdisc-fake.$(OBJEXT) +test_rdisc_fake_OBJECTS = $(am_test_rdisc_fake_OBJECTS) +test_rdisc_fake_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +am_test_rdisc_linux_OBJECTS = test-rdisc-linux.$(OBJEXT) +test_rdisc_linux_OBJECTS = $(am_test_rdisc_linux_OBJECTS) +test_rdisc_linux_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -144,8 +159,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(rdisc_SOURCES) -DIST_SOURCES = $(rdisc_SOURCES) +SOURCES = $(test_rdisc_fake_SOURCES) $(test_rdisc_linux_SOURCES) +DIST_SOURCES = $(test_rdisc_fake_SOURCES) $(test_rdisc_linux_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -170,6 +185,30 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -196,7 +235,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -231,6 +269,7 @@ 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@ @@ -451,10 +490,16 @@ AM_LDFLAGS = \ $(DBUS_LIBS) \ $(CODE_COVERAGE_LDFLAGS) -rdisc_SOURCES = \ - rdisc.c +test_rdisc_linux_SOURCES = \ + test-rdisc-linux.c -rdisc_LDADD = \ +test_rdisc_linux_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +test_rdisc_fake_SOURCES = \ + test-rdisc-fake.c + +test_rdisc_fake_LDADD = \ $(top_builddir)/src/libNetworkManager.la all: all-am @@ -473,7 +518,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rdisc/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/rdisc/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -501,9 +545,13 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list -rdisc$(EXEEXT): $(rdisc_OBJECTS) $(rdisc_DEPENDENCIES) $(EXTRA_rdisc_DEPENDENCIES) - @rm -f rdisc$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(rdisc_OBJECTS) $(rdisc_LDADD) $(LIBS) +test-rdisc-fake$(EXEEXT): $(test_rdisc_fake_OBJECTS) $(test_rdisc_fake_DEPENDENCIES) $(EXTRA_test_rdisc_fake_DEPENDENCIES) + @rm -f test-rdisc-fake$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_rdisc_fake_OBJECTS) $(test_rdisc_fake_LDADD) $(LIBS) + +test-rdisc-linux$(EXEEXT): $(test_rdisc_linux_OBJECTS) $(test_rdisc_linux_DEPENDENCIES) $(EXTRA_test_rdisc_linux_DEPENDENCIES) + @rm -f test-rdisc-linux$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_rdisc_linux_OBJECTS) $(test_rdisc_linux_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -511,21 +559,22 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdisc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rdisc-fake.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rdisc-linux.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -592,6 +641,99 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -623,6 +765,7 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -727,11 +870,11 @@ ps-am: uninstall-am: -.MAKE: install-am install-strip +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ @@ -743,9 +886,13 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ +@VALGRIND_RULES@ + # 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. .NOEXPORT: diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/rdisc/tests/test-rdisc-fake.c new file mode 100644 index 00000000..8b7bd37a --- /dev/null +++ b/src/rdisc/tests/test-rdisc-fake.c @@ -0,0 +1,453 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* rdisc.c - test program + * + * 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, 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) 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> +#include <syslog.h> + +#include "nm-rdisc.h" +#include "nm-fake-rdisc.h" +#include "nm-logging.h" + +#include "nm-fake-platform.h" + +#include "nm-test-utils.h" + +static NMFakeRDisc * +rdisc_new (void) +{ + NMRDisc *rdisc; + const int ifindex = 1; + const char *ifname = nm_platform_link_get_name (ifindex); + + rdisc = nm_fake_rdisc_new (ifindex, ifname); + g_assert (rdisc); + return NM_FAKE_RDISC (rdisc); +} + +static void +match_gateway (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref) +{ + NMRDiscGateway *gw = &g_array_index (array, NMRDiscGateway, idx); + char buf[INET6_ADDRSTRLEN]; + + g_assert_cmpstr (inet_ntop (AF_INET6, &gw->address, buf, sizeof (buf)), ==, addr); + g_assert_cmpint (gw->timestamp, ==, ts); + g_assert_cmpint (gw->lifetime, ==, lt); + g_assert_cmpint (gw->preference, ==, pref); +} + +static void +match_address (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred) +{ + NMRDiscAddress *a = &g_array_index (array, NMRDiscAddress, idx); + char buf[INET6_ADDRSTRLEN]; + + g_assert_cmpstr (inet_ntop (AF_INET6, &a->address, buf, sizeof (buf)), ==, addr); + g_assert_cmpint (a->timestamp, ==, ts); + g_assert_cmpint (a->lifetime, ==, lt); + g_assert_cmpint (a->preferred, ==, preferred); +} + +static void +match_route (GArray *array, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref) +{ + NMRDiscRoute *route = &g_array_index (array, NMRDiscRoute, idx); + char buf[INET6_ADDRSTRLEN]; + + g_assert_cmpstr (inet_ntop (AF_INET6, &route->network, buf, sizeof (buf)), ==, nw); + g_assert_cmpint (route->plen, ==, plen); + g_assert_cmpstr (inet_ntop (AF_INET6, &route->gateway, buf, sizeof (buf)), ==, gw); + g_assert_cmpint (route->timestamp, ==, ts); + g_assert_cmpint (route->lifetime, ==, lt); + g_assert_cmpint (route->preference, ==, pref); +} + +static void +match_dns_server (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt) +{ + NMRDiscDNSServer *dns = &g_array_index (array, NMRDiscDNSServer, idx); + char buf[INET6_ADDRSTRLEN]; + + g_assert_cmpstr (inet_ntop (AF_INET6, &dns->address, buf, sizeof (buf)), ==, addr); + g_assert_cmpint (dns->timestamp, ==, ts); + g_assert_cmpint (dns->lifetime, ==, lt); +} + +static void +match_dns_domain (GArray *array, guint idx, const char *domain, guint32 ts, guint32 lt) +{ + NMRDiscDNSDomain *dns = &g_array_index (array, NMRDiscDNSDomain, idx); + + g_assert_cmpstr (dns->domain, ==, domain); + g_assert_cmpint (dns->timestamp, ==, ts); + g_assert_cmpint (dns->lifetime, ==, lt); +} + +typedef struct { + GMainLoop *loop; + guint counter; + guint rs_counter; + guint32 timestamp1; + guint32 first_solicit; + guint32 timeout_id; +} TestData; + +static void +test_simple_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +{ + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL | + NM_RDISC_CONFIG_GATEWAYS | + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES | + NM_RDISC_CONFIG_DNS_SERVERS | + NM_RDISC_CONFIG_DNS_DOMAINS | + NM_RDISC_CONFIG_HOP_LIMIT | + NM_RDISC_CONFIG_MTU); + g_assert_cmpint (rdisc->dhcp_level, ==, NM_RDISC_DHCP_LEVEL_OTHERCONF); + match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); + match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::1", data->timestamp1, 10); + match_dns_domain (rdisc->dns_domains, 0, "foobar.com", data->timestamp1, 10); + + g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + data->counter++; + g_main_loop_quit (data->loop); +} + +static void +test_simple (void) +{ + NMFakeRDisc *rdisc = rdisc_new (); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; + guint id; + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_OTHERCONF, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10); + nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 10); + nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 10); + + g_signal_connect (rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (test_simple_changed), + &data); + + nm_rdisc_start (NM_RDISC (rdisc)); + g_main_loop_run (data.loop); + g_assert_cmpint (data.counter, ==, 1); + + g_object_unref (rdisc); + g_main_loop_unref (data.loop); +} + +static void +test_everything_rs_sent (NMRDisc *rdisc, TestData *data) +{ + g_assert_cmpint (data->rs_counter, ==, 0); + data->rs_counter++; +} + +static void +test_everything_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +{ + if (data->counter == 0) { + g_assert_cmpint (data->rs_counter, ==, 1); + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL | + NM_RDISC_CONFIG_GATEWAYS | + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES | + NM_RDISC_CONFIG_DNS_SERVERS | + NM_RDISC_CONFIG_DNS_DOMAINS | + NM_RDISC_CONFIG_HOP_LIMIT | + NM_RDISC_CONFIG_MTU); + match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); + match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::1", data->timestamp1, 10); + match_dns_domain (rdisc->dns_domains, 0, "foobar.com", data->timestamp1, 10); + } else if (data->counter == 1) { + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES | + NM_RDISC_CONFIG_DNS_SERVERS | + NM_RDISC_CONFIG_DNS_DOMAINS); + + g_assert_cmpint (rdisc->gateways->len, ==, 1); + match_gateway (rdisc->gateways, 0, "fe80::2", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (rdisc->addresses->len, ==, 1); + match_address (rdisc->addresses, 0, "2001:db8:a:a::2", data->timestamp1, 10, 10); + g_assert_cmpint (rdisc->routes->len, ==, 1); + match_route (rdisc->routes, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1, 10, 10); + g_assert_cmpint (rdisc->dns_servers->len, ==, 1); + match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::2", data->timestamp1, 10); + g_assert_cmpint (rdisc->dns_domains->len, ==, 1); + match_dns_domain (rdisc->dns_domains, 0, "foobar2.com", data->timestamp1, 10); + + g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + g_main_loop_quit (data->loop); + } else + g_assert_not_reached (); + + data->counter++; +} + +static void +test_everything (void) +{ + NMFakeRDisc *rdisc = rdisc_new (); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; + guint id; + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10); + nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 10); + nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 10); + + /* expire everything from the first RA in the second */ + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 0, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 0, 0); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 0, 0); + nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 0); + nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 0); + + /* and add some new stuff */ + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::2", now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::2", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10); + nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::2", now, 10); + nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar2.com", now, 10); + + g_signal_connect (rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (test_everything_changed), + &data); + g_signal_connect (rdisc, + NM_FAKE_RDISC_RS_SENT, + G_CALLBACK (test_everything_rs_sent), + &data); + + nm_rdisc_start (NM_RDISC (rdisc)); + g_main_loop_run (data.loop); + g_assert_cmpint (data.counter, ==, 2); + g_assert_cmpint (data.rs_counter, ==, 1); + + g_object_unref (rdisc); + g_main_loop_unref (data.loop); +} + +static void +test_preference_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +{ + if (data->counter == 1) { + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES); + g_assert_cmpint (rdisc->gateways->len, ==, 2); + match_gateway (rdisc->gateways, 0, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_gateway (rdisc->gateways, 1, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_LOW); + g_assert_cmpint (rdisc->addresses->len, ==, 2); + match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); + match_address (rdisc->addresses, 1, "2001:db8:a:a::2", data->timestamp1 + 1, 10, 10); + g_assert_cmpint (rdisc->routes->len, ==, 2); + match_route (rdisc->routes, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10); + match_route (rdisc->routes, 1, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 5); + } else if (data->counter == 2) { + g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | + NM_RDISC_CONFIG_ADDRESSES | + NM_RDISC_CONFIG_ROUTES); + + g_assert_cmpint (rdisc->gateways->len, ==, 2); + match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1 + 2, 10, NM_RDISC_PREFERENCE_HIGH); + match_gateway (rdisc->gateways, 1, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (rdisc->addresses->len, ==, 2); + match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1 + 2, 10, 10); + match_address (rdisc->addresses, 1, "2001:db8:a:a::2", data->timestamp1 + 1, 10, 10); + g_assert_cmpint (rdisc->routes->len, ==, 2); + match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1 + 2, 10, 15); + match_route (rdisc->routes, 1, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10); + + g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + g_main_loop_quit (data->loop); + } + + data->counter++; +} + +static void +test_preference (void) +{ + NMFakeRDisc *rdisc = rdisc_new (); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; + guint id; + + /* Test that when a low-preference and medium gateway send advertisements, + * that if the low-preference gateway switches to high-preference, we do + * not get duplicates in the gateway list. + */ + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_LOW); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 5); + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::2", ++now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::2", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10); + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", ++now, 10, NM_RDISC_PREFERENCE_HIGH); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + nm_fake_rdisc_add_route (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 15); + + g_signal_connect (rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (test_preference_changed), + &data); + + nm_rdisc_start (NM_RDISC (rdisc)); + g_main_loop_run (data.loop); + g_assert_cmpint (data.counter, ==, 3); + + g_object_unref (rdisc); + g_main_loop_unref (data.loop); +} + +static void +test_dns_solicit_loop_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data) +{ + data->counter++; +} + +static gboolean +success_timeout (TestData *data) +{ + data->timeout_id = 0; + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; +} + +static void +test_dns_solicit_loop_rs_sent (NMFakeRDisc *rdisc, TestData *data) +{ + guint32 now = nm_utils_get_monotonic_timestamp_s (); + guint id; + + if (data->rs_counter > 0 && data->rs_counter < 6) { + if (data->rs_counter == 1) { + data->first_solicit = now; + /* Kill the test after 10 seconds if it hasn't failed yet */ + data->timeout_id = g_timeout_add_seconds (10, (GSourceFunc) success_timeout, data); + } + + /* On all but the first solicitation, which should be triggered by the + * DNS servers reaching 1/2 lifetime, emit a new RA without the DNS + * servers again. + */ + id = nm_fake_rdisc_add_ra (rdisc, 0, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + + nm_fake_rdisc_emit_new_ras (rdisc); + } else if (data->rs_counter >= 6) { + /* Fail if we've sent too many solicitations in the past 4 seconds */ + g_assert_cmpint (now - data->first_solicit, >, 4); + g_source_remove (data->timeout_id); + g_main_loop_quit (data->loop); + } + data->rs_counter++; +} + +static void +test_dns_solicit_loop (void) +{ + NMFakeRDisc *rdisc = rdisc_new (); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now, 0 }; + guint id; + + /* Ensure that no solicitation loop happens when DNS servers or domains + * stop being sent in advertisements. This can happen if two routers + * send RAs, but the one sending DNS info stops responding, or if one + * router removes the DNS info from the RA without zero-lifetiming them + * first. + */ + + id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + g_assert (id); + nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_LOW); + nm_fake_rdisc_add_address (rdisc, id, "2001:db8:a:a::1", now, 10, 10); + nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 6); + + g_signal_connect (rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (test_dns_solicit_loop_changed), + &data); + g_signal_connect (rdisc, + NM_FAKE_RDISC_RS_SENT, + G_CALLBACK (test_dns_solicit_loop_rs_sent), + &data); + + nm_rdisc_start (NM_RDISC (rdisc)); + g_main_loop_run (data.loop); + g_assert_cmpint (data.counter, ==, 3); + + g_object_unref (rdisc); + g_main_loop_unref (data.loop); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT"); + + if (nmtst_test_quick ()) { + g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", str_if_set (g_get_prgname (), "test-rdisc-fake")); + return EXIT_SKIP; + } + + nm_fake_platform_setup (); + + g_test_add_func ("/rdisc/simple", test_simple); + g_test_add_func ("/rdisc/everything-changed", test_everything); + g_test_add_func ("/rdisc/preference-changed", test_preference); + g_test_add_func ("/rdisc/dns-solicit-loop", test_dns_solicit_loop); + + return g_test_run (); +} diff --git a/src/rdisc/tests/rdisc.c b/src/rdisc/tests/test-rdisc-linux.c index d577a63a..9b2ccafd 100644 --- a/src/rdisc/tests/rdisc.c +++ b/src/rdisc/tests/test-rdisc-linux.c @@ -24,51 +24,47 @@ #include <syslog.h> #include "nm-rdisc.h" -#include "nm-fake-rdisc.h" #include "nm-lndp-rdisc.h" #include "nm-logging.h" -#include "nm-fake-platform.h" #include "nm-linux-platform.h" +#include "nm-test-utils.h" + +NMTST_DEFINE (); + int main (int argc, char **argv) { GMainLoop *loop; NMRDisc *rdisc; - NMRDisc *(*new) (int ifindex, const char *ifname); int ifindex = 1; const char *ifname; -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT"); - loop = g_main_loop_new (NULL, FALSE); - nm_logging_setup ("debug", "ip6", NULL, NULL); - openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR, LOG_DAEMON); - - argv++; - if (!g_strcmp0 (argv[0], "--fake")) { - new = nm_fake_rdisc_new; - nm_fake_platform_setup (); - argv++; - } else { - new = nm_lndp_rdisc_new; - nm_linux_platform_setup (); + if (getuid () != 0) { + g_print ("Missing permission: must run as root\n"); + return EXIT_FAILURE; } - if (argv[0]) { - ifname = argv[0]; + loop = g_main_loop_new (NULL, FALSE); + + nm_linux_platform_setup (); + + if (argv[1]) { + ifname = argv[1]; ifindex = nm_platform_link_get_ifindex (ifname); } else { - ifindex = 1; - ifname = nm_platform_link_get_name (ifindex); + g_print ("Missing command line argument \"interface-name\"\n"); + return EXIT_FAILURE; } - rdisc = new (ifindex, ifname); - if (!rdisc) + rdisc = nm_lndp_rdisc_new (ifindex, ifname); + if (!rdisc) { + g_print ("Failed to create NMRDisc instance\n"); return EXIT_FAILURE; + } nm_rdisc_start (rdisc); g_main_loop_run (loop); diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index cc4b1943..8dcda06d 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -330,6 +330,7 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self, priv->chains = g_slist_append (priv->chains, chain); } else { + g_object_unref (agent); error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_FAILED, "Unable to start agent authentication."); @@ -602,11 +603,12 @@ request_next_agent (Request *req) { GError *error = NULL; + req->current_call_id = NULL; + if (req->current) + g_object_unref (req->current); + if (req->pending) { /* Send the request to the next agent */ - req->current_call_id = NULL; - if (req->current) - g_object_unref (req->current); req->current = req->pending->data; req->pending = g_slist_remove (req->pending, req->current); @@ -616,7 +618,6 @@ request_next_agent (Request *req) req->next_callback (req); } else { - req->current_call_id = NULL; req->current = NULL; /* No more secret agents are available to fulfill this secrets request */ diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c index 85b3c400..41f0268d 100644 --- a/src/settings/nm-inotify-helper.c +++ b/src/settings/nm-inotify-helper.c @@ -148,20 +148,20 @@ init_inotify (NMInotifyHelper *self) NMInotifyHelper * nm_inotify_helper_get (void) { - static NMInotifyHelper *singleton = NULL; + static NMInotifyHelper *singleton_instance = NULL; - if (!singleton) { - singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); + if (!singleton_instance) { + singleton_instance = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); - if (!init_inotify (singleton)) { - g_clear_object (&singleton); + if (!init_inotify (singleton_instance)) { + g_clear_object (&singleton_instance); return NULL; } } else - g_object_ref (singleton); + g_object_ref (singleton_instance); - g_assert (singleton); - return singleton; + g_assert (singleton_instance); + return singleton_instance; } static void diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 529f4d8f..ec2052f0 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -82,7 +82,9 @@ enum { PROP_0 = 0, PROP_VISIBLE, PROP_UNSAVED, + PROP_READY, PROP_FLAGS, + PROP_FILENAME, }; enum { @@ -99,6 +101,7 @@ typedef struct { guint session_changed_id; NMSettingsConnectionFlags flags; + gboolean ready; guint updated_idle_id; @@ -129,6 +132,8 @@ typedef struct { gint32 autoconnect_retry_time; NMDeviceStateReason autoconnect_blocked_reason; + char *filename; + } NMSettingsConnectionPrivate; /**************************************************************/ @@ -442,6 +447,7 @@ gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self, NMConnection *new_connection, gboolean update_unsaved, + const char *log_diff_name, GError **error) { NMSettingsConnectionPrivate *priv; @@ -455,6 +461,15 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, if (!nm_connection_normalize (new_connection, NULL, NULL, error)) return FALSE; + if ( nm_connection_get_path (NM_CONNECTION (self)) + && g_strcmp0 (nm_connection_get_uuid (NM_CONNECTION (self)), nm_connection_get_uuid (new_connection)) != 0) { + /* Updating the UUID is not allowed once the path is exported. */ + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "connection %s cannot change the UUID from %s to %s", nm_connection_get_id (NM_CONNECTION (self)), + nm_connection_get_uuid (NM_CONNECTION (self)), nm_connection_get_uuid (new_connection)); + return FALSE; + } + /* Do nothing if there's nothing to update */ if (nm_connection_compare (NM_CONNECTION (self), new_connection, @@ -467,7 +482,8 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, */ g_signal_handlers_block_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE)); - nm_utils_log_connection_diff (new_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, "update connection", "++ "); + if (log_diff_name) + nm_utils_log_connection_diff (new_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ "); nm_connection_replace_settings_from_connection (NM_CONNECTION (self), new_connection); nm_settings_connection_set_flags (self, @@ -519,24 +535,34 @@ ignore_cb (NMSettingsConnection *connection, * subsystems watching this connection. Before returning, 'callback' is run * with the given 'user_data' along with any errors encountered. */ +static void +replace_and_commit (NMSettingsConnection *self, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + GError *error = NULL; + + if (nm_settings_connection_replace_settings (self, new_connection, TRUE, "replace-and-commit-disk", &error)) + nm_settings_connection_commit_changes (self, callback, user_data); + else { + g_assert (error); + if (callback) + callback (self, error, user_data); + g_clear_error (&error); + } +} + void nm_settings_connection_replace_and_commit (NMSettingsConnection *self, NMConnection *new_connection, NMSettingsConnectionCommitFunc callback, gpointer user_data) { - GError *error = NULL; - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); g_return_if_fail (NM_IS_CONNECTION (new_connection)); - if (nm_settings_connection_replace_settings (self, new_connection, TRUE, &error)) { - nm_settings_connection_commit_changes (self, callback, user_data); - } else { - if (callback) - callback (self, error, user_data); - g_clear_error (&error); - } + NM_SETTINGS_CONNECTION_GET_CLASS (self)->replace_and_commit (self, new_connection, callback, user_data); } static void @@ -1350,11 +1376,8 @@ update_auth_cb (NMSettingsConnection *self, con_update_cb, info); } else { - /* Do nothing if there's nothing to update */ - if (!nm_connection_compare (NM_CONNECTION (self), info->new_settings, NM_SETTING_COMPARE_FLAG_EXACT)) { - if (!nm_settings_connection_replace_settings (self, info->new_settings, TRUE, &local)) - g_assert (local); - } + if (!nm_settings_connection_replace_settings (self, info->new_settings, TRUE, "replace-and-commit-memory", &local)) + g_assert (local); con_update_cb (self, local, info); g_clear_error (&local); } @@ -2166,6 +2189,64 @@ nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connectio return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED); } +gboolean +nm_settings_connection_get_ready (NMSettingsConnection *connection) +{ + return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->ready; +} + +void +nm_settings_connection_set_ready (NMSettingsConnection *connection, + gboolean ready) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + + ready = !!ready; + if (priv->ready != ready) { + priv->ready = ready; + g_object_notify (G_OBJECT (connection), NM_SETTINGS_CONNECTION_READY); + } +} + +/** + * nm_settings_connection_set_filename: + * @connection: an #NMSettingsConnection + * @filename: @connection's filename + * + * Called by a backend to sets the filename that @connection is read + * from/written to. + */ +void +nm_settings_connection_set_filename (NMSettingsConnection *connection, + const char *filename) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + + if (g_strcmp0 (filename, priv->filename) != 0) { + g_free (priv->filename); + priv->filename = g_strdup (filename); + g_object_notify (G_OBJECT (connection), NM_SETTINGS_CONNECTION_FILENAME); + } +} + +/** + * nm_settings_connection_get_filename: + * @connection: an #NMSettingsConnection + * + * Gets the filename that @connection was read from/written to. This may be + * %NULL if @connection is unsaved, or if it is associated with a backend that + * does not store each connection in a separate file. + * + * Returns: @connection's filename. + */ +const char * +nm_settings_connection_get_filename (NMSettingsConnection *connection) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + + return priv->filename; +} + /**************************************************************/ static void @@ -2174,6 +2255,7 @@ nm_settings_connection_init (NMSettingsConnection *self) NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); priv->visible = FALSE; + priv->ready = TRUE; priv->session_monitor = nm_session_monitor_get (); priv->session_changed_id = g_signal_connect (priv->session_monitor, @@ -2235,6 +2317,8 @@ dispose (GObject *object) } g_clear_object (&priv->agent_mgr); + g_clear_pointer (&priv->filename, g_free); + G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); } @@ -2252,9 +2336,15 @@ get_property (GObject *object, guint prop_id, case PROP_UNSAVED: g_value_set_boolean (value, nm_settings_connection_get_unsaved (self)); break; + case PROP_READY: + g_value_set_boolean (value, nm_settings_connection_get_ready (self)); + break; case PROP_FLAGS: g_value_set_uint (value, nm_settings_connection_get_flags (self)); break; + case PROP_FILENAME: + g_value_set_string (value, nm_settings_connection_get_filename (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2268,9 +2358,15 @@ set_property (GObject *object, guint prop_id, NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); switch (prop_id) { + case PROP_READY: + nm_settings_connection_set_ready (self, g_value_get_boolean (value)); + break; case PROP_FLAGS: nm_settings_connection_set_flags_all (self, g_value_get_uint (value)); break; + case PROP_FILENAME: + nm_settings_connection_set_filename (self, g_value_get_string (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2289,6 +2385,7 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) object_class->get_property = get_property; object_class->set_property = set_property; + class->replace_and_commit = replace_and_commit; class->commit_changes = commit_changes; class->delete = do_delete; class->supports_secrets = supports_secrets; @@ -2309,6 +2406,13 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_PARAM_STATIC_STRINGS)); g_object_class_install_property + (object_class, PROP_READY, + g_param_spec_boolean (NM_SETTINGS_CONNECTION_READY, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_FLAGS, g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", NM_SETTINGS_CONNECTION_FLAGS_NONE, @@ -2317,6 +2421,13 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_FILENAME, + g_param_spec_string (NM_SETTINGS_CONNECTION_FILENAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* Signals */ /* Emitted when the connection is changed for any reason */ diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 254e927b..49661f38 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -46,9 +46,11 @@ G_BEGIN_DECLS #define NM_SETTINGS_CONNECTION_UPDATED_BY_USER "updated-by-user" /* Properties */ -#define NM_SETTINGS_CONNECTION_VISIBLE "visible" -#define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" -#define NM_SETTINGS_CONNECTION_FLAGS "flags" +#define NM_SETTINGS_CONNECTION_VISIBLE "visible" +#define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" +#define NM_SETTINGS_CONNECTION_READY "ready" +#define NM_SETTINGS_CONNECTION_FLAGS "flags" +#define NM_SETTINGS_CONNECTION_FILENAME "filename" /** @@ -95,6 +97,11 @@ struct _NMSettingsConnectionClass { GObjectClass parent; /* virtual methods */ + void (*replace_and_commit) (NMSettingsConnection *connection, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + void (*commit_changes) (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data); @@ -116,6 +123,7 @@ void nm_settings_connection_commit_changes (NMSettingsConnection *connection, gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self, NMConnection *new_connection, gboolean update_unsaved, + const char *log_diff_name, GError **error); void nm_settings_connection_replace_and_commit (NMSettingsConnection *self, @@ -196,6 +204,14 @@ gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connectio gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection); gboolean nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection); +gboolean nm_settings_connection_get_ready (NMSettingsConnection *connection); +void nm_settings_connection_set_ready (NMSettingsConnection *connection, + gboolean ready); + +void nm_settings_connection_set_filename (NMSettingsConnection *connection, + const char *filename); +const char *nm_settings_connection_get_filename (NMSettingsConnection *connection); + G_END_DECLS #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 9ed03f69..9d40b06e 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -151,6 +151,8 @@ typedef struct { GSList *unmanaged_specs; GSList *unrecognized_specs; GSList *get_connections_cache; + + gboolean startup_complete; } NMSettingsPrivate; #define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate)) @@ -175,11 +177,43 @@ enum { PROP_HOSTNAME, PROP_CAN_MODIFY, PROP_CONNECTIONS, + PROP_STARTUP_COMPLETE, LAST_PROP }; static void +check_startup_complete (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + NMSettingsConnection *conn; + + if (priv->startup_complete) + return; + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) { + if (!nm_settings_connection_get_ready (conn)) + return; + } + + priv->startup_complete = TRUE; + g_object_notify (G_OBJECT (self), NM_SETTINGS_STARTUP_COMPLETE); +} + +static void +connection_ready_changed (NMSettingsConnection *conn, + GParamSpec *pspec, + gpointer user_data) +{ + NMSettings *self = NM_SETTINGS (user_data); + + if (nm_settings_connection_get_ready (conn)) + check_startup_complete (self); +} + +static void plugin_connection_added (NMSystemConfigInterface *config, NMSettingsConnection *connection, gpointer user_data) @@ -772,6 +806,7 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated_by_user), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self); + g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); /* Forget about the connection internally */ g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, @@ -784,6 +819,8 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_REMOVED, connection); g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTIONS); + check_startup_complete (self); + g_object_unref (connection); } @@ -850,6 +887,7 @@ claim_connection (NMSettings *self, GHashTableIter iter; gpointer data; char *path; + NMSettingsConnection *existing; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -868,6 +906,23 @@ claim_connection (NMSettings *self, return; } + existing = nm_settings_get_connection_by_uuid (self, nm_connection_get_uuid (NM_CONNECTION (connection))); + if (existing) { + /* Cannot add duplicate connections per UUID. Just return without action and + * log a warning. + * + * This means, that plugins must not provide duplicate connections (UUID). + * In fact, none of the plugins currently would do that. + * + * But globaly, over different setting plugins, there could be duplicates + * without the individual plugins being aware. Don't handle that at all, just + * error out. That should not happen unless the admin misconfigured the system + * to create conflicting connections. */ + nm_log_warn (LOGD_SETTINGS, "plugin provided duplicate connection with UUID %s", + nm_connection_get_uuid (NM_CONNECTION (connection))); + return; + } + /* Read timestamp from look-aside file and put it into the connection's data */ nm_settings_connection_read_and_fill_timestamp (connection); @@ -889,6 +944,11 @@ claim_connection (NMSettings *self, g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE, G_CALLBACK (connection_visibility_changed), self); + if (!priv->startup_complete) { + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY, + G_CALLBACK (connection_ready_changed), + self); + } /* Export the connection over D-Bus */ g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -1780,6 +1840,16 @@ cp_get_connection_by_uuid (NMConnectionProvider *provider, const char *uuid) /***************************************************************/ +gboolean +nm_settings_get_startup_complete (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + + return priv->startup_complete; +} + +/***************************************************************/ + NMSettings * nm_settings_new (GError **error) { @@ -1800,6 +1870,7 @@ nm_settings_new (GError **error) } load_connections (self); + check_startup_complete (self); nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_SETTINGS, self); return self; @@ -1900,6 +1971,9 @@ get_property (GObject *object, guint prop_id, g_ptr_array_add (array, g_strdup (path)); g_value_take_boxed (value, array); break; + case PROP_STARTUP_COMPLETE: + g_value_set_boolean (value, nm_settings_get_startup_complete (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 520c4ec3..9c0a4c83 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -37,10 +37,11 @@ #define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS)) #define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass)) -#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" -#define NM_SETTINGS_HOSTNAME "hostname" -#define NM_SETTINGS_CAN_MODIFY "can-modify" -#define NM_SETTINGS_CONNECTIONS "connections" +#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" +#define NM_SETTINGS_HOSTNAME "hostname" +#define NM_SETTINGS_CAN_MODIFY "can-modify" +#define NM_SETTINGS_CONNECTIONS "connections" +#define NM_SETTINGS_STARTUP_COMPLETE "connections" #define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added" #define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated" @@ -120,4 +121,6 @@ void nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean qu gint nm_settings_sort_connections (gconstpointer a, gconstpointer b); +gboolean nm_settings_get_startup_complete (NMSettings *self); + #endif /* __NM_SETTINGS_H__ */ diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in index 1e9b0fdd..ea45e2a5 100644 --- a/src/settings/plugins/Makefile.in +++ b/src/settings/plugins/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -83,7 +93,6 @@ host_triplet = @host@ @CONFIG_PLUGIN_IFUPDOWN_TRUE@am__append_4 = ifupdown @CONFIG_PLUGIN_IFNET_TRUE@am__append_5 = ifnet subdir = src/settings/plugins -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -100,6 +109,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -159,6 +169,7 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = keyfile example ibft ifcfg-rh ifcfg-suse ifupdown ifnet +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -210,7 +221,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -245,6 +255,7 @@ 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@ @@ -462,7 +473,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -757,6 +767,8 @@ uninstall-am: mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/example/Makefile.in b/src/settings/plugins/example/Makefile.in index baa5c698..dabbdc74 100644 --- a/src/settings/plugins/example/Makefile.in +++ b/src/settings/plugins/example/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/example -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -175,6 +184,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -201,7 +212,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -236,6 +246,7 @@ 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@ @@ -483,7 +494,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/example/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/example/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -532,14 +542,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -757,6 +767,8 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + # 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/src/settings/plugins/example/nm-example-connection.c b/src/settings/plugins/example/nm-example-connection.c index 2f0b20a0..e1259611 100644 --- a/src/settings/plugins/example/nm-example-connection.c +++ b/src/settings/plugins/example/nm-example-connection.c @@ -82,6 +82,7 @@ nm_example_connection_new (const char *full_path, if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, TRUE, + NULL, error)) { g_object_unref (object); object = NULL; diff --git a/src/settings/plugins/ibft/Makefile.in b/src/settings/plugins/ibft/Makefile.in index 415961df..405c213b 100644 --- a/src/settings/plugins/ibft/Makefile.in +++ b/src/settings/plugins/ibft/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ibft -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -225,6 +234,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -276,7 +287,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -311,6 +321,7 @@ 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@ @@ -558,7 +569,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ibft/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ibft/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -644,14 +654,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -948,6 +958,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/ibft/nm-ibft-connection.c b/src/settings/plugins/ibft/nm-ibft-connection.c index 5459a705..c6a9054e 100644 --- a/src/settings/plugins/ibft/nm-ibft-connection.c +++ b/src/settings/plugins/ibft/nm-ibft-connection.c @@ -46,6 +46,7 @@ nm_ibft_connection_new (const GPtrArray *block, GError **error) if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), source, FALSE, + NULL, error)) g_clear_object (&object); diff --git a/src/settings/plugins/ibft/plugin.c b/src/settings/plugins/ibft/plugin.c index 303971e0..632c4df1 100644 --- a/src/settings/plugins/ibft/plugin.c +++ b/src/settings/plugins/ibft/plugin.c @@ -63,7 +63,7 @@ read_connections (SCPluginIbft *self) NMIbftConnection *connection; if (!read_ibft_blocks ("/sbin/iscsiadm", &blocks, &error)) { - nm_log_dbg (LOGD_SETTINGS, _("ibft: failed to read iscsiadm records: %s"), error->message); + nm_log_dbg (LOGD_SETTINGS, "ibft: failed to read iscsiadm records: %s", error->message); g_error_free (error); return; } @@ -71,13 +71,13 @@ read_connections (SCPluginIbft *self) for (iter = blocks; iter; iter = iter->next) { connection = nm_ibft_connection_new (iter->data, &error); if (connection) { - nm_log_info (LOGD_SETTINGS, _("ibft: read connection '%s'"), + nm_log_info (LOGD_SETTINGS, "ibft: read connection '%s'", nm_connection_get_id (NM_CONNECTION (connection))); g_hash_table_insert (priv->connections, g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), connection); } else { - nm_log_warn (LOGD_SETTINGS, _("ibft: failed to read iscsiadm record: %s"), error->message); + nm_log_warn (LOGD_SETTINGS, "ibft: failed to read iscsiadm record: %s", error->message); g_clear_error (&error); } } diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c index 066a79f2..e89d9b08 100644 --- a/src/settings/plugins/ibft/reader.c +++ b/src/settings/plugins/ibft/reader.c @@ -186,6 +186,7 @@ done: if (lines) g_strfreev (lines); g_free (out); + g_free (err); if (success) *out_blocks = blocks; else diff --git a/src/settings/plugins/ibft/tests/Makefile.am b/src/settings/plugins/ibft/tests/Makefile.am index dd72220a..3c7c94ac 100644 --- a/src/settings/plugins/ibft/tests/Makefile.am +++ b/src/settings/plugins/ibft/tests/Makefile.am @@ -32,6 +32,7 @@ test_ibft_SOURCES = \ test_ibft_LDADD = \ $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-ibft endif diff --git a/src/settings/plugins/ibft/tests/Makefile.in b/src/settings/plugins/ibft/tests/Makefile.in index e2f06169..d682318a 100644 --- a/src/settings/plugins/ibft/tests/Makefile.in +++ b/src/settings/plugins/ibft/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-ibft$(EXEEXT) @ENABLE_TESTS_TRUE@TESTS = test-ibft$(EXEEXT) subdir = src/settings/plugins/ibft/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -196,6 +205,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -222,7 +233,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -257,6 +267,7 @@ 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@ @@ -512,7 +523,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ibft/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ibft/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -558,14 +568,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -891,9 +901,13 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ +@ENABLE_TESTS_TRUE@@VALGRIND_RULES@ + # 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. .NOEXPORT: diff --git a/src/settings/plugins/ibft/tests/test-ibft.c b/src/settings/plugins/ibft/tests/test-ibft.c index 2ff249af..980a9cee 100644 --- a/src/settings/plugins/ibft/tests/test-ibft.c +++ b/src/settings/plugins/ibft/tests/test-ibft.c @@ -63,7 +63,7 @@ read_block (const char *iscsiadm_path, const char *expected_mac) } g_assert (block); - g_slist_foreach (blocks, (GFunc) g_ptr_array_unref, NULL); + g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref); return block; } @@ -110,6 +110,7 @@ test_read_ibft_dhcp (void) g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); g_object_unref (connection); + g_ptr_array_unref (block); } static void @@ -266,7 +267,7 @@ test_read_ibft_vlan (void) g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, NULL); g_object_unref (connection); - g_ptr_array_ref (block); + g_ptr_array_unref (block); } NMTST_DEFINE (); @@ -275,7 +276,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); g_test_add_func (TPATH "ibft/dhcp", test_read_ibft_dhcp); g_test_add_func (TPATH "ibft/static", test_read_ibft_static); diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in index 5d396273..89511983 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,7 +16,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -80,8 +90,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifcfg-rh -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -98,6 +106,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -228,6 +237,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -279,7 +290,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -314,6 +324,7 @@ 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@ @@ -579,7 +590,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -668,14 +678,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -998,6 +1008,8 @@ uninstall-am: uninstall-dbusserviceDATA uninstall-pkglibLTLIBRARIES tags tags-am uninstall uninstall-am uninstall-dbusserviceDATA \ uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index d78f3752..0ec355ee 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -26,7 +26,9 @@ #define IFCFG_TAG "ifcfg-" #define KEYS_TAG "keys-" #define ROUTE_TAG "route-" +#define RULE_TAG "rule-" #define ROUTE6_TAG "route6-" +#define RULE6_TAG "rule6-" #define BAK_TAG ".bak" #define TILDE_TAG "~" @@ -39,7 +41,7 @@ #define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts" #define IFCFG_PLUGIN_NAME "ifcfg-rh" -#define IFCFG_PLUGIN_INFO "(c) 2007 - 2013 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." +#define IFCFG_PLUGIN_INFO "(c) 2007 - 2015 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." #define TYPE_ETHERNET "Ethernet" #define TYPE_WIRELESS "Wireless" diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 7596cbd5..94d22258 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -33,6 +33,8 @@ #include <nm-setting-pppoe.h> #include <nm-setting-wireless-security.h> #include <nm-setting-8021x.h> +#include <nm-platform.h> +#include <nm-logging.h> #include "common.h" #include "nm-config.h" @@ -49,7 +51,6 @@ G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTI typedef struct { gulong ih_event_id; - char *path; int file_wd; char *keyfile; @@ -63,6 +64,9 @@ typedef struct { char *unmanaged_spec; char *unrecognized_spec; + + gulong devtimeout_link_changed_handler; + guint devtimeout_timeout_id; } NMIfcfgConnectionPrivate; enum { @@ -80,6 +84,101 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +static gboolean +devtimeout_ready (gpointer user_data) +{ + NMIfcfgConnection *self = user_data; + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); + + priv->devtimeout_timeout_id = 0; + nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE); + return FALSE; +} + +static void +link_changed (NMPlatform *platform, int ifindex, NMPlatformLink *link, + NMPlatformSignalChangeType change_type, NMPlatformReason reason, + NMConnection *self) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); + const char *ifname; + + ifname = nm_connection_get_interface_name (self); + if (g_strcmp0 (link->name, ifname) != 0) + return; + + /* Shouldn't happen, but... */ + if (change_type == NM_PLATFORM_SIGNAL_REMOVED) + return; + + nm_log_info (LOGD_SETTINGS, "Device %s appeared; connection '%s' now ready", + ifname, nm_connection_get_id (self)); + + g_signal_handler_disconnect (platform, priv->devtimeout_link_changed_handler); + priv->devtimeout_link_changed_handler = 0; + g_source_remove (priv->devtimeout_timeout_id); + + /* Don't declare the connection ready right away, since NMManager may not have + * started processing the device yet. + */ + priv->devtimeout_timeout_id = g_idle_add (devtimeout_ready, self); +} + +static gboolean +devtimeout_expired (gpointer user_data) +{ + NMIfcfgConnection *self = user_data; + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); + + nm_log_info (LOGD_SETTINGS, "Device for connection '%s' did not appear before timeout", + nm_connection_get_id (NM_CONNECTION (self))); + + g_signal_handler_disconnect (nm_platform_get (), priv->devtimeout_link_changed_handler); + priv->devtimeout_link_changed_handler = 0; + priv->devtimeout_timeout_id = 0; + + nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), TRUE); + return FALSE; +} + +static void +nm_ifcfg_connection_check_devtimeout (NMIfcfgConnection *self) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); + NMSettingConnection *s_con; + const char *ifname; + const char *filename; + guint devtimeout; + + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); + + if (!nm_setting_connection_get_autoconnect (s_con)) + return; + ifname = nm_setting_connection_get_interface_name (s_con); + if (!ifname) + return; + filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (self)); + if (!filename) + return; + devtimeout = devtimeout_from_file (filename); + if (!devtimeout) + return; + + if (nm_platform_link_get_ifindex (ifname) != 0) + return; + + /* ONBOOT=yes, DEVICE and DEVTIMEOUT are set, but device is not present */ + nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), FALSE); + + nm_log_info (LOGD_SETTINGS, "Waiting %u seconds for %s to appear for connection '%s'", + devtimeout, ifname, nm_connection_get_id (NM_CONNECTION (self))); + + priv->devtimeout_link_changed_handler = + g_signal_connect (nm_platform_get (), NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK (link_changed), self); + priv->devtimeout_timeout_id = g_timeout_add_seconds (devtimeout, devtimeout_expired, self); +} + static void files_changed_cb (NMInotifyHelper *ih, struct inotify_event *evt, @@ -102,8 +201,7 @@ files_changed_cb (NMInotifyHelper *ih, NMIfcfgConnection * nm_ifcfg_connection_new (NMConnection *source, const char *full_path, - GError **error, - gboolean *ignore_error) + GError **error) { GObject *object; NMConnection *tmp; @@ -117,18 +215,9 @@ nm_ifcfg_connection_new (NMConnection *source, if (source) tmp = g_object_ref (source); else { - char *keyfile = NULL, *routefile = NULL, *route6file = NULL; - - tmp = connection_from_file (full_path, NULL, NULL, + tmp = connection_from_file (full_path, &unhandled_spec, - &keyfile, - &routefile, - &route6file, - error, - ignore_error); - g_free (keyfile); - g_free (routefile); - g_free (route6file); + error); if (!tmp) return NULL; @@ -142,6 +231,7 @@ nm_ifcfg_connection_new (NMConnection *source, unrecognized_spec = unhandled_spec + strlen ("unrecognized:"); object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, + NM_SETTINGS_CONNECTION_FILENAME, full_path, NM_IFCFG_CONNECTION_UNMANAGED_SPEC, unmanaged_spec, NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec, NULL); @@ -149,11 +239,10 @@ nm_ifcfg_connection_new (NMConnection *source, if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, update_unsaved, - error)) { - /* Set the path and start monitoring */ - if (full_path) - nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path); - } else + NULL, + error)) + nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object)); + else g_clear_object (&object); g_object_unref (tmp); @@ -161,14 +250,6 @@ nm_ifcfg_connection_new (NMConnection *source, return (NMIfcfgConnection *) object; } -const char * -nm_ifcfg_connection_get_path (NMIfcfgConnection *self) -{ - g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); - - return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path; -} - static void path_watch_stop (NMIfcfgConnection *self) { @@ -209,17 +290,21 @@ path_watch_stop (NMIfcfgConnection *self) } } -void -nm_ifcfg_connection_set_path (NMIfcfgConnection *self, const char *ifcfg_path) +static void +filename_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { + NMIfcfgConnection *self = NM_IFCFG_CONNECTION (object); NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); - - g_return_if_fail (ifcfg_path != NULL); + const char *ifcfg_path; path_watch_stop (self); - g_free (priv->path); - priv->path = g_strdup (ifcfg_path); + ifcfg_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (self)); + if (!ifcfg_path) + return; + priv->keyfile = utils_get_keys_path (ifcfg_path); priv->routefile = utils_get_route_path (ifcfg_path); priv->route6file = utils_get_route6_path (ifcfg_path); @@ -252,6 +337,28 @@ nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self) } static void +replace_and_commit (NMSettingsConnection *connection, + NMConnection *new_connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + const char *filename; + GError *error = NULL; + + filename = nm_settings_connection_get_filename (connection); + if (filename && utils_has_complex_routes (filename)) { + if (callback) { + error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file"); + callback (connection, error, user_data); + g_clear_error (&error); + } + } + + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->replace_and_commit (connection, new_connection, callback, user_data); +} + +static void commit_changes (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data) @@ -261,16 +368,15 @@ commit_changes (NMSettingsConnection *connection, NMConnection *reread; gboolean same = FALSE, success = FALSE; char *ifcfg_path = NULL; + const char *filename; /* To ensure we don't rewrite files that are only changed from other * processes on-disk, read the existing connection back in and only rewrite * it if it's really changed. */ - if (priv->path) { - reread = connection_from_file (priv->path, NULL, NULL, - NULL, NULL, NULL, NULL, - &error, NULL); - g_clear_error (&error); + filename = nm_settings_connection_get_filename (connection); + if (filename) { + reread = connection_from_file (filename, NULL, NULL); if (reread) { same = nm_connection_compare (NM_CONNECTION (connection), reread, @@ -288,7 +394,7 @@ commit_changes (NMSettingsConnection *connection, success = writer_update_connection (NM_CONNECTION (connection), IFCFG_DIR, - priv->path, + filename, priv->keyfile, &error); } else { @@ -297,7 +403,7 @@ commit_changes (NMSettingsConnection *connection, &ifcfg_path, &error); if (success) { - nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (connection), ifcfg_path); + nm_settings_connection_set_filename (connection, ifcfg_path); g_free (ifcfg_path); } } @@ -318,14 +424,15 @@ do_delete (NMSettingsConnection *connection, gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); + const char *filename; - if (priv->path) { - g_unlink (priv->path); + filename = nm_settings_connection_get_filename (connection); + if (filename) { + g_unlink (filename); if (priv->keyfile) g_unlink (priv->keyfile); if (priv->routefile) g_unlink (priv->routefile); - if (priv->route6file) g_unlink (priv->route6file); } @@ -338,6 +445,8 @@ do_delete (NMSettingsConnection *connection, static void nm_ifcfg_connection_init (NMIfcfgConnection *connection) { + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FILENAME, + G_CALLBACK (filename_changed), NULL); } static void @@ -381,17 +490,21 @@ get_property (GObject *object, guint prop_id, static void dispose (GObject *object) { - path_watch_stop (NM_IFCFG_CONNECTION (object)); + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); - G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->dispose (object); -} + path_watch_stop (NM_IFCFG_CONNECTION (object)); -static void -finalize (GObject *object) -{ - g_free (NM_IFCFG_CONNECTION_GET_PRIVATE (object)->path); + if (priv->devtimeout_link_changed_handler) { + g_signal_handler_disconnect (nm_platform_get (), + priv->devtimeout_link_changed_handler); + priv->devtimeout_link_changed_handler = 0; + } + if (priv->devtimeout_timeout_id) { + g_source_remove (priv->devtimeout_timeout_id); + priv->devtimeout_timeout_id = 0; + } - G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); + G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->dispose (object); } static void @@ -406,8 +519,8 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; - object_class->finalize = finalize; settings_class->delete = do_delete; + settings_class->replace_and_commit = replace_and_commit; settings_class->commit_changes = commit_changes; /* Properties */ diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 37eacaf0..328e58f5 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -48,13 +48,7 @@ GType nm_ifcfg_connection_get_type (void); NMIfcfgConnection *nm_ifcfg_connection_new (NMConnection *source, const char *full_path, - GError **error, - gboolean *ignore_error); - -const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self); - -void nm_ifcfg_connection_set_path (NMIfcfgConnection *self, - const char *ifcfg_path); + GError **error); const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self); const char *nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self); diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index 2dced56b..b7efa864 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -58,10 +58,31 @@ #include "reader.h" #include "writer.h" #include "utils.h" +#include "gsystem-local-alloc.h" #define DBUS_SERVICE_NAME "com.redhat.ifcfgrh1" #define DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1" + +#define _LOG_DEFAULT_DOMAIN LOGD_SETTINGS + +#define _LOG(level, domain, ...) \ + G_STMT_START { \ + nm_log ((level), (domain), \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + "ifcfg-rh: " \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + +#define _LOGT(...) _LOG (LOGL_TRACE, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGD(...) _LOG (LOGL_DEBUG, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGI(...) _LOG (LOGL_INFO, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGW(...) _LOG (LOGL_WARN, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGE(...) _LOG (LOGL_ERR, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) + +#define ERR_GET_MSG(err) (((err) && (err)->message) ? (err)->message : "(unknown)") + + static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, const char *in_ifcfg, const char **out_uuid, @@ -70,10 +91,13 @@ static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, #include "nm-ifcfg-rh-glue.h" -static void connection_new_or_changed (SCPluginIfcfg *plugin, - const char *path, - NMIfcfgConnection *existing, - char **out_old_path); +static NMIfcfgConnection *update_connection (SCPluginIfcfg *plugin, + NMConnection *source, + const char *full_path, + NMIfcfgConnection *connection, + gboolean protect_existing_connection, + GHashTable *protected_connections, + GError **error); static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); @@ -104,13 +128,22 @@ typedef struct { static void connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) { - SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); + SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); const char *path; - path = nm_ifcfg_connection_get_path (connection); + path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); g_return_if_fail (path != NULL); - connection_new_or_changed (plugin, path, connection, NULL); + + if (!priv->ifcfg_monitor) { + _LOGD ("connection_ifcfg_changed("NM_IFCFG_CONNECTION_LOG_FMTD"): %s", NM_IFCFG_CONNECTION_LOG_ARGD (connection), "ignore event"); + return; + } + + _LOGD ("connection_ifcfg_changed("NM_IFCFG_CONNECTION_LOG_FMTD"): %s", NM_IFCFG_CONNECTION_LOG_ARGD (connection), "reload"); + + update_connection (self, NULL, path, connection, TRUE, NULL, NULL); } static void @@ -120,69 +153,6 @@ connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) nm_connection_get_uuid (NM_CONNECTION (obj))); } -static NMIfcfgConnection * -_internal_new_connection (SCPluginIfcfg *self, - const char *path, - NMConnection *source, - GError **error) -{ - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - NMIfcfgConnection *connection; - const char *cid; - GError *local = NULL; - gboolean ignore_error = FALSE; - - if (!source) - nm_log_info (LOGD_SETTINGS, "parsing %s ... ", path); - - connection = nm_ifcfg_connection_new (source, path, &local, &ignore_error); - if (!connection) { - if (!ignore_error) - nm_log_warn (LOGD_SETTINGS, " %s", (local && local->message) ? local->message : "(unknown)"); - if (local) - g_propagate_error (error, local); - else - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "(unknown)"); - return NULL; - } - - cid = nm_connection_get_id (NM_CONNECTION (connection)); - g_assert (cid); - - g_hash_table_insert (priv->connections, - g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), - connection); - nm_log_info (LOGD_SETTINGS, " read connection '%s'", cid); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (connection_removed_cb), - self); - - if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { - const char *spec; - const char *device_id; - - spec = nm_ifcfg_connection_get_unmanaged_spec (connection); - device_id = strchr (spec, ':'); - if (device_id) - device_id++; - else - device_id = spec; - nm_log_warn (LOGD_SETTINGS, " Ignoring connection '%s' / device '%s' due to NM_CONTROLLED=no.", - cid, device_id); - } else if (nm_ifcfg_connection_get_unrecognized_spec (connection)) { - nm_log_warn (LOGD_SETTINGS, " Ignoring connection '%s' of unrecognized type.", cid); - } - - /* watch changes of ifcfg hardlinks */ - g_signal_connect (G_OBJECT (connection), "ifcfg-changed", - G_CALLBACK (connection_ifcfg_changed), self); - - return connection; -} - -/* Monitoring */ - static void remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) { @@ -192,6 +162,8 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) g_return_if_fail (self != NULL); g_return_if_fail (connection != NULL); + _LOGI ("remove "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection)); + unmanaged = !!nm_ifcfg_connection_get_unmanaged_spec (connection); unrecognized = !!nm_ifcfg_connection_get_unrecognized_spec (connection); @@ -212,160 +184,233 @@ find_by_path (SCPluginIfcfg *self, const char *path) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); GHashTableIter iter; - NMIfcfgConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; g_return_val_if_fail (path != NULL, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (path, nm_ifcfg_connection_get_path (candidate)) == 0) - return candidate; + if (g_strcmp0 (path, nm_settings_connection_get_filename (candidate)) == 0) + return NM_IFCFG_CONNECTION (candidate); } return NULL; } static NMIfcfgConnection * -find_by_uuid_from_path (SCPluginIfcfg *self, const char *path) +update_connection (SCPluginIfcfg *self, + NMConnection *source, + const char *full_path, + NMIfcfgConnection *connection, + gboolean protect_existing_connection, + GHashTable *protected_connections, + GError **error) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - char *uuid; - - g_return_val_if_fail (path != NULL, NULL); + NMIfcfgConnection *connection_new; + NMIfcfgConnection *connection_by_uuid; + GError *local = NULL; + const char *new_unmanaged = NULL, *old_unmanaged = NULL; + const char *new_unrecognized = NULL, *old_unrecognized = NULL; + gboolean unmanaged_changed = FALSE, unrecognized_changed = FALSE; + const char *uuid; - uuid = uuid_from_file (path); - if (uuid) - return g_hash_table_lookup (priv->connections, uuid); - else + g_return_val_if_fail (!source || NM_IS_CONNECTION (source), NULL); + g_return_val_if_fail (full_path || source, NULL); + + if (full_path) + _LOGD ("loading from file \"%s\"...", full_path); + + /* Create a NMIfcfgConnection instance, either by reading from @full_path or + * based on @source. */ + connection_new = nm_ifcfg_connection_new (source, full_path, error); + if (!connection_new) { + /* Unexpected failure. Probably the file is invalid? */ + if ( connection + && !protect_existing_connection + && (!protected_connections || !g_hash_table_contains (protected_connections, connection))) + remove_connection (self, connection); return NULL; -} + } -static void -connection_new_or_changed (SCPluginIfcfg *self, - const char *path, - NMIfcfgConnection *existing, - char **out_old_path) -{ - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - NMIfcfgConnection *new; - GError *error = NULL; - gboolean ignore_error = FALSE; - const char *new_unmanaged = NULL, *old_unmanaged = NULL; - const char *new_unrecognized = NULL, *old_unrecognized = NULL; - gboolean unmanaged_changed, unrecognized_changed; + uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new)); + connection_by_uuid = g_hash_table_lookup (priv->connections, uuid); - g_return_if_fail (self != NULL); - g_return_if_fail (path != NULL); + if ( connection + && connection != connection_by_uuid) { - if (out_old_path) - *out_old_path = NULL; - - if (!existing) { - /* See if it's a rename */ - existing = find_by_uuid_from_path (self, path); - if (existing) { - const char *old_path = nm_ifcfg_connection_get_path (existing); - nm_log_info (LOGD_SETTINGS, "renaming %s -> %s", old_path, path); - if (out_old_path) - *out_old_path = g_strdup (old_path); - nm_ifcfg_connection_set_path (existing, path); - } - } + if ( (protect_existing_connection && connection_by_uuid != NULL) + || (protected_connections && g_hash_table_contains (protected_connections, connection))) { + NMIfcfgConnection *conflicting = (protect_existing_connection && connection_by_uuid != NULL) ? connection_by_uuid : connection; - if (!existing) { - /* New connection */ - new = _internal_new_connection (self, path, NULL, NULL); - if (new) { - if (nm_ifcfg_connection_get_unmanaged_spec (new)) - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); - else if (nm_ifcfg_connection_get_unrecognized_spec (new)) - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED); + if (source) + _LOGW ("cannot update protected connection "NM_IFCFG_CONNECTION_LOG_FMT" due to conflicting UUID %s", NM_IFCFG_CONNECTION_LOG_ARG (conflicting), uuid); else - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); + _LOGW ("cannot load %s due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, full_path, NM_IFCFG_CONNECTION_LOG_ARG (conflicting)); + g_object_unref (connection_new); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot update protected connection due to conflicting UUID"); + return NULL; } - return; - } - - new = (NMIfcfgConnection *) nm_ifcfg_connection_new (NULL, path, &error, &ignore_error); - if (!new) { - /* errors reading connection; remove it */ - if (!ignore_error) - nm_log_warn (LOGD_SETTINGS, " %s", (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - nm_log_info (LOGD_SETTINGS, "removed %s.", path); - remove_connection (self, existing); - return; + /* The new connection has a different UUID then the original one that we + * are about to update. Remove @connection. */ + remove_connection (self, connection); } - /* Successfully read connection changes */ + /* Check if the found connection with the same UUID is not protected from updating. */ + if ( connection_by_uuid + && ( (!connection && protect_existing_connection) + || (protected_connections && g_hash_table_contains (protected_connections, connection_by_uuid)))) { + if (source) + _LOGW ("cannot update connection due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_by_uuid)); + else + _LOGW ("cannot load %s due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, full_path, NM_IFCFG_CONNECTION_LOG_ARG (connection_by_uuid)); + g_object_unref (connection_new); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Skip updating protected connection during reload"); + return NULL; + } - old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing)); - new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new)); + /* Evaluate unmanaged/unrecognized flags. */ + if (connection_by_uuid) + old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection_by_uuid); + new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection_new); unmanaged_changed = g_strcmp0 (old_unmanaged, new_unmanaged); - old_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (NM_IFCFG_CONNECTION (existing)); - new_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (NM_IFCFG_CONNECTION (new)); + if (connection_by_uuid) + old_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (connection_by_uuid); + new_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (connection_new); unrecognized_changed = g_strcmp0 (old_unrecognized, new_unrecognized); - if ( !unmanaged_changed - && !unrecognized_changed - && nm_connection_compare (NM_CONNECTION (existing), - NM_CONNECTION (new), - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { - g_object_unref (new); - return; - } + if (connection_by_uuid) { + const char *old_path; + + old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)); + + if ( !unmanaged_changed + && !unrecognized_changed + && nm_connection_compare (NM_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { + if (old_path && g_strcmp0 (old_path, full_path) != 0) + _LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT" without other changes", nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)), NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + } else { + + /******************************************************* + * UPDATE + *******************************************************/ + + if (source) + _LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT" from %s", NM_IFCFG_CONNECTION_LOG_ARG (connection_new), NM_IFCFG_CONNECTION_LOG_PATH (old_path)); + else if (!g_strcmp0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new)))) + _LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + else if (old_path) + _LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT, old_path, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + else + _LOGI ("update and persist "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + + g_object_set (connection_by_uuid, + NM_IFCFG_CONNECTION_UNMANAGED_SPEC, new_unmanaged, + NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, new_unrecognized, + NULL); + + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), + FALSE, /* don't set Unsaved */ + "ifcfg-update", + &local)) { + /* Shouldn't ever get here as 'connection_new' was verified by the reader already + * and the UUID did not change. */ + g_assert_not_reached (); + } + g_assert_no_error (local); + + if (new_unmanaged || new_unrecognized) { + if (!old_unmanaged && !old_unrecognized) { + g_object_ref (connection_by_uuid); + /* Unexport the connection by telling the settings service it's + * been removed. + */ + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection_by_uuid)); + /* Remove the path so that claim_connection() doesn't complain later when + * interface gets managed and connection is re-added. */ + nm_connection_set_path (NM_CONNECTION (connection_by_uuid), NULL); + + /* signal_remove() will end up removing the connection from our hash, + * so add it back now. + */ + g_hash_table_insert (priv->connections, + g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))), + connection_by_uuid); + } + } else { + if (old_unmanaged /* && !new_unmanaged */) { + _LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" and its device because NM_CONTROLLED was true.", + NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_by_uuid); + } else if (old_unrecognized /* && !new_unrecognized */) { + _LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" because it is now a recognized type.", + NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_by_uuid); + } + } - nm_log_info (LOGD_SETTINGS, "updating %s", path); - g_object_set (existing, - NM_IFCFG_CONNECTION_UNMANAGED_SPEC, new_unmanaged, - NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, new_unrecognized, - NULL); - - if (new_unmanaged || new_unrecognized) { - if (!old_unmanaged && !old_unrecognized) { - g_object_ref (existing); - /* Unexport the connection by telling the settings service it's - * been removed. - */ - nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (existing)); - /* Remove the path so that claim_connection() doesn't complain later when - * interface gets managed and connection is re-added. */ - nm_connection_set_path (NM_CONNECTION (existing), NULL); - - /* signal_remove() will end up removing the connection from our hash, - * so add it back now. - */ - g_hash_table_insert (priv->connections, - g_strdup (nm_connection_get_uuid (NM_CONNECTION (existing))), - existing); + if (unmanaged_changed) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + if (unrecognized_changed) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED); } + nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (connection_by_uuid), full_path); + g_object_unref (connection_new); + return connection_by_uuid; } else { - const char *cid = nm_connection_get_id (NM_CONNECTION (new)); - - if (old_unmanaged /* && !new_unmanaged */) { - nm_log_info (LOGD_SETTINGS, "Managing connection '%s' and its device because NM_CONTROLLED was true.", cid); - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing); - } else if (old_unrecognized /* && !new_unrecognized */) { - nm_log_info (LOGD_SETTINGS, "Managing connection '%s' because it is now a recognized type.", cid); - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing); - } - if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (existing), - NM_CONNECTION (new), - FALSE, /* don't set Unsaved */ - &error)) { - /* Shouldn't ever get here as 'new' was verified by the reader already */ - g_assert_no_error (error); + /******************************************************* + * ADD + *******************************************************/ + + if (source) + _LOGI ("add connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + else + _LOGI ("new connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new); + + g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); + + if (nm_ifcfg_connection_get_unmanaged_spec (connection_new)) { + const char *spec; + const char *device_id; + + spec = nm_ifcfg_connection_get_unmanaged_spec (connection_new); + device_id = strchr (spec, ':'); + if (device_id) + device_id++; + else + device_id = spec; + _LOGW ("Ignoring connection "NM_IFCFG_CONNECTION_LOG_FMT" / device '%s' due to NM_CONTROLLED=no.", + NM_IFCFG_CONNECTION_LOG_ARG (connection_new), device_id); + } else if (nm_ifcfg_connection_get_unrecognized_spec (connection_new)) + _LOGW ("Ignoring connection "NM_IFCFG_CONNECTION_LOG_FMT" of unrecognized type.", NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); + + /* watch changes of ifcfg hardlinks */ + g_signal_connect (G_OBJECT (connection_new), "ifcfg-changed", + G_CALLBACK (connection_ifcfg_changed), self); + + if (!source) { + /* Only raise the signal if we were called without source, i.e. if we read the connection from file. + * Otherwise, we were called by add_connection() which does not expect the signal. */ + if (nm_ifcfg_connection_get_unmanaged_spec (connection_new)) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + else if (nm_ifcfg_connection_get_unrecognized_spec (connection_new)) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED); + else + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_new); } + return connection_new; } - g_object_unref (new); - - if (unmanaged_changed) - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); - if (unrecognized_changed) - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED); } static void @@ -385,6 +430,8 @@ ifcfg_dir_changed (GFileMonitor *monitor, return; } + _LOGD ("ifcfg_dir_changed(%s) = %d", path, event_type); + base = g_file_get_basename (file); if (utils_is_ifcfg_alias_file (base, NULL)) { /* Alias file changed. Get the base ifcfg file from it */ @@ -397,14 +444,13 @@ ifcfg_dir_changed (GFileMonitor *monitor, connection = find_by_path (plugin, ifcfg_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: - nm_log_info (LOGD_SETTINGS, "removed %s.", ifcfg_path); if (connection) remove_connection (plugin, connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: /* Update or new */ - connection_new_or_changed (plugin, ifcfg_path, connection, NULL); + update_connection (plugin, NULL, ifcfg_path, connection, TRUE, NULL, NULL); break; default: break; @@ -433,6 +479,43 @@ setup_ifcfg_monitoring (SCPluginIfcfg *plugin) } } +static GHashTable * +_paths_from_connections (GHashTable *connections) +{ + GHashTableIter iter; + NMIfcfgConnection *connection; + GHashTable *paths = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_iter_init (&iter, connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + const char *path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); + + if (path) + g_hash_table_add (paths, (void *) path); + } + return paths; +} + +static int +_sort_paths (const char **f1, const char **f2, GHashTable *paths) +{ + struct stat st; + gboolean c1, c2; + gint64 m1, m2; + + c1 = !!g_hash_table_contains (paths, *f1); + c2 = !!g_hash_table_contains (paths, *f2); + if (c1 != c2) + return c1 ? -1 : 1; + + m1 = stat (*f1, &st) == 0 ? (gint64) st.st_mtime : G_MININT64; + m2 = stat (*f2, &st) == 0 ? (gint64) st.st_mtime : G_MININT64; + if (m1 != m2) + return m1 > m2 ? -1 : 1; + + return strcmp (*f1, *f2); +} + static void read_connections (SCPluginIfcfg *plugin) { @@ -440,28 +523,26 @@ read_connections (SCPluginIfcfg *plugin) GDir *dir; GError *err = NULL; const char *item; - GHashTable *oldconns; + GHashTable *alive_connections; GHashTableIter iter; - gpointer key, value; NMIfcfgConnection *connection; + GPtrArray *dead_connections = NULL; + guint i; + GPtrArray *filenames; + GHashTable *paths; dir = g_dir_open (IFCFG_DIR, 0, &err); if (!dir) { - nm_log_warn (LOGD_SETTINGS, "Could not read directory '%s': %s", IFCFG_DIR, err->message); + _LOGW ("Could not read directory '%s': %s", IFCFG_DIR, err->message); g_error_free (err); return; } - oldconns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - const char *ifcfg_path = nm_ifcfg_connection_get_path (value); - if (ifcfg_path) - g_hash_table_insert (oldconns, g_strdup (ifcfg_path), value); - } + alive_connections = g_hash_table_new (NULL, NULL); + filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { - char *full_path, *old_path; + char *full_path; if (utils_should_ignore_file (item, TRUE)) continue; @@ -470,31 +551,45 @@ read_connections (SCPluginIfcfg *plugin) full_path = g_build_filename (IFCFG_DIR, item, NULL); if (!utils_get_ifcfg_name (full_path, TRUE)) - goto next; + g_free (full_path); + else + g_ptr_array_add (filenames, full_path); + } + g_dir_close (dir); - connection = g_hash_table_lookup (oldconns, full_path); - g_hash_table_remove (oldconns, full_path); - connection_new_or_changed (plugin, full_path, connection, &old_path); + /* While reloading, we don't replace connections that we already loaded while + * iterating over the files. + * + * To have sensible, reproducible behavior, sort the paths by last modification + * time prefering older files. + */ + paths = _paths_from_connections (priv->connections); + g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths); + g_hash_table_destroy (paths); + + for (i = 0; i < filenames->len; i++) { + connection = update_connection (plugin, NULL, filenames->pdata[i], NULL, FALSE, alive_connections, NULL); + if (connection) + g_hash_table_add (alive_connections, connection); + } + g_ptr_array_free (filenames, TRUE); - if (old_path) { - g_hash_table_remove (oldconns, old_path); - g_free (old_path); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + if ( !g_hash_table_contains (alive_connections, connection) + && nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))) { + if (!dead_connections) + dead_connections = g_ptr_array_new (); + g_ptr_array_add (dead_connections, connection); } - - next: - g_free (full_path); } + g_hash_table_destroy (alive_connections); - g_dir_close (dir); - - g_hash_table_iter_init (&iter, oldconns); - while (g_hash_table_iter_next (&iter, &key, &value)) { - nm_log_info (LOGD_SETTINGS, "removed %s.", (char *)key); - g_hash_table_iter_remove (&iter); - remove_connection (plugin, value); + if (dead_connections) { + for (i = 0; i < dead_connections->len; i++) + remove_connection (plugin, dead_connections->pdata[i]); + g_ptr_array_free (dead_connections, TRUE); } - - g_hash_table_destroy (oldconns); } static GSList * @@ -540,7 +635,7 @@ load_connection (NMSystemConfigInterface *config, return FALSE; connection = find_by_path (plugin, filename); - connection_new_or_changed (plugin, filename, connection, NULL); + update_connection (plugin, NULL, filename, connection, TRUE, NULL, NULL); if (!connection) connection = find_by_path (plugin, filename); @@ -605,8 +700,7 @@ add_connection (NMSystemConfigInterface *config, GError **error) { SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); - NMIfcfgConnection *added = NULL; - char *path = NULL; + gs_free char *path = NULL; /* Ensure we reject attempts to add the connection long before we're * asked to write it to disk. @@ -618,10 +712,7 @@ add_connection (NMSystemConfigInterface *config, if (!writer_new_connection (connection, IFCFG_DIR, &path, error)) return NULL; } - - added = _internal_new_connection (self, path, connection, error); - g_free (path); - return (NMSettingsConnection *) added; + return NM_SETTINGS_CONNECTION (update_connection (self, connection, path, NULL, FALSE, NULL, error)); } #define SC_NETWORK_FILE "/etc/sysconfig/network" @@ -641,7 +732,7 @@ plugin_get_hostname (SCPluginIfcfg *plugin) network = svOpenFile (SC_NETWORK_FILE, NULL); if (!network) { - nm_log_warn (LOGD_SETTINGS, "Could not get hostname: failed to read " SC_NETWORK_FILE); + _LOGW ("Could not get hostname: failed to read " SC_NETWORK_FILE); return NULL; } @@ -693,7 +784,7 @@ plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname) #endif if (!ret) { - nm_log_warn (LOGD_SETTINGS, "Could not save hostname: failed to create/open " HOSTNAME_FILE); + _LOGW ("Could not save hostname: failed to create/open " HOSTNAME_FILE); g_free (hostname_eol); return FALSE; } @@ -862,7 +953,7 @@ sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (!priv->bus) { - nm_log_warn (LOGD_SETTINGS, "Couldn't connect to D-Bus: %s", error->message); + _LOGW ("Couldn't connect to D-Bus: %s", error->message); g_clear_error (&error); } else { DBusConnection *tmp; @@ -883,10 +974,10 @@ sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) G_TYPE_INVALID, G_TYPE_UINT, &result, G_TYPE_INVALID)) { - nm_log_warn (LOGD_SETTINGS, "Couldn't acquire D-Bus service: %s", error->message); + _LOGW ("Couldn't acquire D-Bus service: %s", error->message); g_clear_error (&error); } else if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - nm_log_warn (LOGD_SETTINGS, "Couldn't acquire ifcfgrh1 D-Bus service (already taken)"); + _LOGW ("Couldn't acquire ifcfgrh1 D-Bus service (already taken)"); } else success = TRUE; } @@ -1048,7 +1139,7 @@ nm_system_config_factory (void) dbus_g_connection_register_g_object (priv->bus, DBUS_OBJECT_PATH, G_OBJECT (singleton)); - nm_log_info (LOGD_SETTINGS, "Acquired D-Bus service %s", DBUS_SERVICE_NAME); + _LOGI ("Acquired D-Bus service %s", DBUS_SERVICE_NAME); } else g_object_ref (singleton); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 145a0a39..41439f61 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -56,6 +56,7 @@ #include "nm-posix-signals.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" +#include "gsystem-local-alloc.h" #include "common.h" #include "shvar.h" @@ -292,9 +293,11 @@ get_numbered_tag (char *tag_name, int which) } static gboolean -is_any_ip4_address_defined (shvarFile *ifcfg) +is_any_ip4_address_defined (shvarFile *ifcfg, int *idx) { - int i; + int i, ignore, *ret_idx;; + + ret_idx = idx ? idx : &ignore; for (i = -1; i <= 2; i++) { char *tag; @@ -305,6 +308,7 @@ is_any_ip4_address_defined (shvarFile *ifcfg) g_free (tag); if (value) { g_free (value); + *ret_idx = i; return TRUE; } @@ -313,6 +317,7 @@ is_any_ip4_address_defined (shvarFile *ifcfg) g_free(tag); if (value) { g_free (value); + *ret_idx = i; return TRUE; } @@ -321,6 +326,7 @@ is_any_ip4_address_defined (shvarFile *ifcfg) g_free(tag); if (value) { g_free (value); + *ret_idx = i; return TRUE; } } @@ -534,8 +540,6 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * char **lines = NULL, **iter; GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; GMatchInfo *match_info; - NMIPRoute *route = NULL; - char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; gint64 prefix_int, metric_int; gboolean success = FALSE; @@ -567,6 +571,9 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * /* Iterate through file lines */ lines = g_strsplit_set (contents, "\n\r", -1); for (iter = lines; iter && *iter; iter++) { + gs_free char *next_hop = NULL, *dest = NULL; + char *prefix, *metric; + NMIPRoute *route; /* Skip empty lines */ if (g_regex_match_simple (pattern_empty, *iter, 0, 0)) @@ -586,11 +593,10 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * } dest = g_match_info_fetch (match_info, 1); if (!strcmp (dest, "default")) - strcpy (dest, "0.0.0.0"); + strcpy (dest, "0.0.0.0"); if (!nm_utils_ipaddr_valid (AF_INET, dest)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route destination address '%s'", dest); - g_free (dest); g_match_info_free (match_info); goto error; } @@ -605,7 +611,6 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * if (errno || prefix_int <= 0 || prefix_int > 32) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route destination prefix '%s'", prefix); - g_free (dest); g_free (prefix); goto error; } @@ -621,13 +626,10 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * "Invalid IP4 route gateway address '%s'", next_hop); g_match_info_free (match_info); - g_free (dest); - g_free (next_hop); goto error; } } else { /* we don't make distinction between missing GATEWAY IP and 0.0.0.0 */ - next_hop = NULL; } g_match_info_free (match_info); @@ -642,8 +644,6 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * g_match_info_free (match_info); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route metric '%s'", metric); - g_free (dest); - g_free (next_hop); g_free (metric); goto error; } @@ -652,13 +652,11 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * g_match_info_free (match_info); route = nm_ip_route_new (AF_INET, dest, prefix_int, next_hop, metric_int, error); - if (!route) { - g_free (dest); - g_free (next_hop); + if (!route) goto error; - } if (!nm_setting_ip_config_add_route (s_ip4, route)) PARSE_WARNING ("duplicate IP4 route"); + nm_ip_route_unref (route); } success = TRUE; @@ -666,8 +664,6 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError * error: g_free (contents); g_strfreev (lines); - if (route) - nm_ip_route_unref (route); g_regex_unref (regex_to1); g_regex_unref (regex_to2); g_regex_unref (regex_via); @@ -743,7 +739,6 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error char **lines = NULL, **iter; GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; GMatchInfo *match_info; - NMIPRoute *route = NULL; char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; gint64 prefix_int, metric_int; gboolean success = FALSE; @@ -776,6 +771,7 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error /* Iterate through file lines */ lines = g_strsplit_set (contents, "\n\r", -1); for (iter = lines; iter && *iter; iter++) { + NMIPRoute *route; /* Skip empty lines */ if (g_regex_match_simple (pattern_empty, *iter, 0, 0)) @@ -865,6 +861,7 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error goto error; if (!nm_setting_ip_config_add_route (s_ip6, route)) PARSE_WARNING ("duplicate IP6 route"); + nm_ip_route_unref (route); } success = TRUE; @@ -872,8 +869,6 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error error: g_free (contents); g_strfreev (lines); - if (route) - nm_ip_route_unref (route); g_regex_unref (regex_to1); g_regex_unref (regex_to2); g_regex_unref (regex_via); @@ -892,7 +887,7 @@ make_ip4_setting (shvarFile *ifcfg, char *value = NULL; char *route_path = NULL; char *method; - char *gateway = NULL; + gs_free char *gateway = NULL; gint32 i; shvarFile *network_ifcfg; shvarFile *route_ifcfg; @@ -930,7 +925,7 @@ make_ip4_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "BOOTPROTO", FALSE); if (!value || !*value || !g_ascii_strcasecmp (value, "none")) { - if (is_any_ip4_address_defined (ifcfg)) + if (is_any_ip4_address_defined (ifcfg, NULL)) method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; else method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; @@ -946,11 +941,25 @@ make_ip4_setting (shvarFile *ifcfg, NULL); return NM_SETTING (s_ip4); } else if (!g_ascii_strcasecmp (value, "shared")) { + int idx; + g_free (value); g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); + /* 1 IP address is allowed for shared connections. Read it. */ + if (is_any_ip4_address_defined (ifcfg, &idx)) { + NMIPAddress *addr = NULL; + + if (!read_full_ip4_address (ifcfg, network_file, idx, NULL, &addr, NULL, error)) + goto done; + if (!read_ip4_address (ifcfg, "GATEWAY", &gateway, error)) + goto done; + (void) nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); + } return NM_SETTING (s_ip4); } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -966,6 +975,8 @@ make_ip4_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10, + -1, G_MAXUINT32, -1), NULL); if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) @@ -997,6 +1008,8 @@ make_ip4_setting (shvarFile *ifcfg, for (i = -1; i < 256; i++) { NMIPAddress *addr = NULL; + /* gateway will only be set if still unset. Hence, we don't leak gateway + * here by calling read_full_ip4_address() repeatedly */ if (!read_full_ip4_address (ifcfg, network_file, i, NULL, &addr, &gateway, error)) goto done; @@ -1075,14 +1088,10 @@ make_ip4_setting (shvarFile *ifcfg, /* Static routes - route-<name> file */ route_path = utils_get_route_path (ifcfg->fileName); - if (!route_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Could not get route file path for '%s'", ifcfg->fileName); - goto done; - } - /* First test new/legacy syntax */ - if (utils_has_route_file_new_syntax (route_path)) { + if (utils_has_complex_routes (route_path)) { + PARSE_WARNING ("'rule-' or 'rule6-' file is present; you will need to use a dispatcher script to apply these routes"); + } else if (utils_has_route_file_new_syntax (route_path)) { /* Parse route file in new syntax */ route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE); if (route_ifcfg) { @@ -1107,6 +1116,7 @@ make_ip4_setting (shvarFile *ifcfg, if (!read_route_file_legacy (route_path, s_ip4, error)) goto done; } + g_free (route_path); /* Legacy value NM used for a while but is incorrect (rh #459370) */ if (!nm_setting_ip_config_get_num_dns_searches (s_ip4)) { @@ -1132,7 +1142,6 @@ make_ip4_setting (shvarFile *ifcfg, return NM_SETTING (s_ip4); done: - g_free (gateway); g_free (route_path); g_object_unref (s_ip4); return NULL; @@ -1362,6 +1371,8 @@ make_ip6_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10, + -1, G_MAXUINT32, -1), NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val, NULL); @@ -1467,18 +1478,15 @@ make_ip6_setting (shvarFile *ifcfg, /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ - /* Read static routes from route6-<interface> file */ - route6_path = utils_get_route6_path (ifcfg->fileName); - if (!route6_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Could not get route6 file path for '%s'", ifcfg->fileName); - goto error; - } + if (!utils_has_complex_routes (ifcfg->fileName)) { + /* Read static routes from route6-<interface> file */ + route6_path = utils_get_route6_path (ifcfg->fileName); + if (!read_route6_file (route6_path, s_ip6, error)) + goto error; - if (!read_route6_file (route6_path, s_ip6, error)) - goto error; + g_free (route6_path); + } - g_free (route6_path); return NM_SETTING (s_ip6); error: @@ -3061,7 +3069,8 @@ make_wpa_setting (shvarFile *ifcfg, if (psk) { g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); g_free (psk); - } + } else if (error) + goto error; } if (adhoc) @@ -3174,6 +3183,8 @@ make_wireless_security_setting (shvarFile *ifcfg, { NMSetting *wsec; + g_return_val_if_fail (error && !*error, NULL); + if (!adhoc) { wsec = make_leap_setting (ifcfg, file, error); if (wsec) @@ -3425,11 +3436,11 @@ wireless_connection_from_ifcfg (const char *file, char *printable_ssid = NULL; const char *mode; gboolean adhoc = FALSE; + GError *local = NULL; g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (*error == NULL, NULL); + g_return_val_if_fail (!error || !*error, NULL); connection = nm_simple_connection_new (); @@ -3453,10 +3464,11 @@ wireless_connection_from_ifcfg (const char *file, adhoc = TRUE; /* Wireless security */ - security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, error); - if (*error) { + security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, &local); + if (local) { g_free (printable_ssid); g_object_unref (connection); + g_propagate_error (error, local); return NULL; } if (security_setting) { @@ -3838,7 +3850,8 @@ handle_bond_option (NMSettingBond *s_bond, } if (!nm_setting_bond_add_option (s_bond, key, sanitized ? sanitized : value)) - PARSE_WARNING ("invalid bonding option '%s'", key); + PARSE_WARNING ("invalid bonding option '%s' = %s", + key, sanitized ? sanitized : value); g_free (sanitized); } @@ -4443,6 +4456,7 @@ make_vlan_setting (shvarFile *ifcfg, goto error; } g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); + g_clear_pointer (&parent, g_free); if (svTrueValue (ifcfg, "REORDER_HDR", FALSE)) vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS; @@ -4461,6 +4475,8 @@ make_vlan_setting (shvarFile *ifcfg, parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); + g_free (iface_name); + return (NMSetting *) s_vlan; error: @@ -4624,32 +4640,24 @@ check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) } } -NMConnection * -connection_from_file (const char *filename, - const char *network_file, /* for unit tests only */ - const char *test_type, /* for unit tests only */ - char **out_unhandled, - char **out_keyfile, - char **out_routefile, - char **out_route6file, - GError **error, - gboolean *out_ignore_error) +static NMConnection * +connection_from_file_full (const char *filename, + const char *network_file, /* for unit tests only */ + const char *test_type, /* for unit tests only */ + char **out_unhandled, + GError **error, + gboolean *out_ignore_error) { NMConnection *connection = NULL; shvarFile *parsed; - char *type, *devtype, *bootproto; + gs_free char *type = NULL; + char *devtype, *bootproto; NMSetting *s_ip4, *s_ip6, *s_port, *s_dcb = NULL; const char *ifcfg_name = NULL; g_return_val_if_fail (filename != NULL, NULL); if (out_unhandled) g_return_val_if_fail (*out_unhandled == NULL, NULL); - if (out_keyfile) - g_return_val_if_fail (*out_keyfile == NULL, NULL); - if (out_routefile) - g_return_val_if_fail (*out_routefile == NULL, NULL); - if (out_route6file) - g_return_val_if_fail (*out_route6file == NULL, NULL); /* Non-NULL only for unit tests; normally use /etc/sysconfig/network */ if (!network_file) @@ -4685,8 +4693,7 @@ connection_from_file (const char *filename, g_free (bootproto); goto done; } - - type = NULL; + g_free (bootproto); devtype = svGetValue (parsed, "DEVICETYPE", FALSE); if (devtype) { @@ -4775,7 +4782,6 @@ connection_from_file (const char *filename, PARSE_WARNING ("connection type was unrecognized but device was not uniquely identified; device may be managed"); goto done; } - g_free (type); if (!connection) goto done; @@ -4827,15 +4833,64 @@ connection_from_file (const char *filename, connection = NULL; } - if (out_keyfile) - *out_keyfile = utils_get_keys_path (filename); - if (out_routefile) - *out_routefile = utils_get_route_path (filename); - if (out_route6file) - *out_route6file = utils_get_route6_path (filename); - done: svCloseFile (parsed); return connection; } +NMConnection * +connection_from_file (const char *filename, + char **out_unhandled, + GError **error) +{ + gboolean ignore_error = FALSE; + NMConnection *conn; + + conn = connection_from_file_full (filename, NULL, NULL, + out_unhandled, + error, + &ignore_error); + if (error && *error && !ignore_error) + PARSE_WARNING ("%s", (*error)->message); + return conn; +} + +NMConnection * +connection_from_file_test (const char *filename, + const char *network_file, + const char *test_type, + char **out_unhandled, + GError **error) +{ + return connection_from_file_full (filename, + network_file, + test_type, + out_unhandled, + error, + NULL); +} + +guint +devtimeout_from_file (const char *filename) +{ + shvarFile *ifcfg; + char *devtimeout_str; + guint devtimeout; + + g_return_val_if_fail (filename != NULL, 0); + + ifcfg = svOpenFile (filename, NULL); + if (!ifcfg) + return 0; + + devtimeout_str = svGetValue (ifcfg, "DEVTIMEOUT", FALSE); + if (devtimeout_str) { + devtimeout = nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0); + g_free (devtimeout_str); + } else + devtimeout = 0; + + svCloseFile (ifcfg); + + return devtimeout; +} diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h index c23e5870..70e9ce4e 100644 --- a/src/settings/plugins/ifcfg-rh/reader.h +++ b/src/settings/plugins/ifcfg-rh/reader.h @@ -27,15 +27,18 @@ #include "shvar.h" NMConnection *connection_from_file (const char *filename, - const char *network_file, /* for unit tests only */ - const char *test_type, /* for unit tests only */ char **out_unhandled, - char **out_keyfile, - char **out_routefile, - char **out_route6file, - GError **error, - gboolean *out_ignore_error); + GError **error); char *uuid_from_file (const char *filename); +guint devtimeout_from_file (const char *filename); + +/* for test-ifcfg-rh */ +NMConnection *connection_from_file_test (const char *filename, + const char *network_file, + const char *test_type, + char **out_unhandled, + GError **error); + #endif /* __READER_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 6c9769b2..5f3d173b 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -372,10 +372,12 @@ svSetValue (shvarFile *s, const char *key, const char *value, gboolean verbatim) if (oldval) { /* delete line */ s->lineList = g_list_remove_link (s->lineList, s->current); + g_free (s->current->data); g_list_free_1 (s->current); s->modified = TRUE; } - goto bail; /* do not need keyValue */ + g_free (keyValue); + goto end; } if (!oldval) { @@ -387,21 +389,19 @@ svSetValue (shvarFile *s, const char *key, const char *value, gboolean verbatim) if (strcmp (oldval, newval) != 0) { /* change line */ - if (s->current) + if (s->current) { + g_free (s->current->data); s->current->data = keyValue; - else + } else s->lineList = g_list_append (s->lineList, keyValue); s->modified = TRUE; - } + } else + g_free (keyValue); end: g_free (newval); g_free (oldval); return; - - bail: - g_free (keyValue); - goto end; } /* Write the current contents iff modified. Returns FALSE on error diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am index 5a17ed9b..a3f6a052 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am @@ -47,6 +47,7 @@ test_ifcfg_rh_utils_SOURCES = \ test_ifcfg_rh_utils_LDADD = \ $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-ifcfg-rh-utils test-ifcfg-rh endif diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in index f34e759d..d3c838a7 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -83,8 +93,6 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@TESTS = test-ifcfg-rh-utils$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-ifcfg-rh$(EXEEXT) subdir = src/settings/plugins/ifcfg-rh/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -101,6 +109,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -226,6 +235,8 @@ am__tty_colors = { \ fi; \ } DIST_SUBDIRS = network-scripts +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -277,7 +288,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -312,6 +322,7 @@ 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@ @@ -570,7 +581,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -624,14 +634,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1073,9 +1083,13 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am +.PRECIOUS: Makefile + @ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ +@ENABLE_TESTS_TRUE@@VALGRIND_RULES@ + # 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. .NOEXPORT: diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 8941da3a..a20a78d9 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -9,10 +9,12 @@ EXTRA_DIST = \ ifcfg-test-wired-static-bootproto \ ifcfg-test-wired-dhcp \ ifcfg-test-wired-dhcp-plus-ip \ + ifcfg-test-wired-shared-plus-ip \ ifcfg-test-wired-dhcp-send-hostname \ ifcfg-test-wired-dhcp6-only \ ifcfg-test-wired-global-gateway \ network-test-wired-global-gateway \ + ifcfg-test-wired-obsolete-gateway-n \ ifcfg-test-wired-never-default \ network-test-wired-never-default \ ifcfg-test-wired-defroute-no \ @@ -106,6 +108,7 @@ EXTRA_DIST = \ ifcfg-test-bond-main \ ifcfg-test-bond-slave \ ifcfg-test-bond-slave-ib \ + ifcfg-test-bond-mode-numeric \ ifcfg-test-dcb \ ifcfg-test-dcb-default-app-priorities \ ifcfg-test-dcb-bad-booleans \ 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 aac646f8..58798f77 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,7 +88,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifcfg-rh/tests/network-scripts -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -95,6 +104,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -119,6 +129,7 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -145,7 +156,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -180,6 +190,7 @@ 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@ @@ -391,10 +402,12 @@ EXTRA_DIST = \ ifcfg-test-wired-static-bootproto \ ifcfg-test-wired-dhcp \ ifcfg-test-wired-dhcp-plus-ip \ + ifcfg-test-wired-shared-plus-ip \ ifcfg-test-wired-dhcp-send-hostname \ ifcfg-test-wired-dhcp6-only \ ifcfg-test-wired-global-gateway \ network-test-wired-global-gateway \ + ifcfg-test-wired-obsolete-gateway-n \ ifcfg-test-wired-never-default \ network-test-wired-never-default \ ifcfg-test-wired-defroute-no \ @@ -488,6 +501,7 @@ EXTRA_DIST = \ ifcfg-test-bond-main \ ifcfg-test-bond-slave \ ifcfg-test-bond-slave-ib \ + ifcfg-test-bond-mode-numeric \ ifcfg-test-dcb \ ifcfg-test-dcb-default-app-priorities \ ifcfg-test-dcb-bad-booleans \ @@ -532,7 +546,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -712,6 +725,8 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am +.PRECIOUS: Makefile + dist-hook: @for f in $(ALIAS_FILES); do \ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-mode-numeric b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-mode-numeric new file mode 100644 index 00000000..9989f58b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-mode-numeric @@ -0,0 +1,5 @@ +DEVICE=bond0 +ONBOOT=no +TYPE=Bond +BOOTPROTO=dhcp +BONDING_OPTS="mode=4 miimon=100" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main index 8507628e..ee7a8dc6 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main @@ -3,6 +3,6 @@ ONBOOT=no TYPE=Bridge BOOTPROTO=dhcp STP=on -DELAY=0 +DELAY=2 BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352" MACADDR=00:16:41:11:22:33 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open index 48db45b2..b089103d 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open @@ -12,3 +12,5 @@ ONBOOT=yes USERCTL=yes PEERDNS=yes IPV6INIT=no +IPV4_ROUTE_METRIC=104 +IPV6_ROUTE_METRIC=106 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp-plus-ip b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp-plus-ip index f0c022a9..af254f9c 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp-plus-ip +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp-plus-ip @@ -15,11 +15,11 @@ DNS3=1:2:3:4::a DNS4=1:2:3:4::b # additional IPs -IPADDR0=1.2.3.4 -PREFIX0=24 -GATEWAY0=1.1.1.1 +IPADDR=1.2.3.4 +PREFIX=24 IPADDR1=9.8.7.6 PREFIX1=16 +GATEWAY=1.1.1.1 IPV6ADDR="1001:abba::1234/56" IPV6ADDR_SECONDARIES="2001:abba::2234/64 3001:abba::3234/96" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 index cad0f6cf..1bc3d524 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 @@ -5,8 +5,8 @@ HWADDR=00:11:22:33:44:ee BOOTPROTO=none IPADDR0=1.2.3.4 PREFIX0=24 -GATEWAY0=1.1.1.1 IPADDR1=9.8.7.6 PREFIX1=16 IPADDR2=3.3.3.3 PREFIX2=8 +GATEWAY=1.1.1.1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 index ad9290a4..d7273e36 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 @@ -5,10 +5,7 @@ HWADDR=00:11:22:33:44:ee BOOTPROTO=none IPADDR=1.2.3.4 PREFIX=24 -GATEWAY=1.1.1.1 IPADDR2=9.8.7.6 PREFIX2=16 -GATEWAY2=5.5.5.5 IPADDR3=3.3.3.3 PREFIX3=8 -GATEWAY3=7.7.7.7 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-obsolete-gateway-n b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-obsolete-gateway-n new file mode 100644 index 00000000..2190a995 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-obsolete-gateway-n @@ -0,0 +1,13 @@ +# GATEWAY<N> is obsolete, but we read it for backwards compatibility + +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes + +# manual IP +IPADDR1=1.2.3.4 +PREFIX1=24 +GATEWAY1=1.1.1.1 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-shared-plus-ip b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-shared-plus-ip new file mode 100644 index 00000000..5098aef7 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-shared-plus-ip @@ -0,0 +1,19 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=shared +ONBOOT=no +IPV6INIT=yes + +# additional IPs +IPADDR=10.20.30.5 +PREFIX=24 +GATEWAY=1.1.1.1 + +# these are ignored for shared method +IPADDR1=6.7.8.9 +PREFIX1=16 +IPADDR2=3.3.3.3 +PREFIX2=24 + diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c index d82a3270..13f1126e 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c @@ -121,7 +121,7 @@ int main (int argc, char **argv) { char *base; - nmtst_init (&argc, &argv, TRUE); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); /* The tests */ test_get_ifcfg_name ("get-ifcfg-name-bad", "/foo/bar/adfasdfadf", FALSE, NULL); diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 4a6940d0..d2fb6867 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -194,8 +194,8 @@ test_read_basic (void) guint64 expected_timestamp = 0; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-minimal", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-minimal", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -254,8 +254,8 @@ test_read_miscellaneous_variables (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-misc-variables", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-misc-variables", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_no_error (error); g_assert (connection); @@ -304,8 +304,8 @@ test_read_variables_corner_cases (void) guint64 expected_timestamp = 0; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-variables-corner-cases-1", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-variables-corner-cases-1", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -350,10 +350,10 @@ test_read_unmanaged (void) guint64 expected_timestamp = 0; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled", - NULL, TYPE_ETHERNET, - &unhandled_spec, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled", + NULL, TYPE_ETHERNET, + &unhandled_spec, + &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -377,16 +377,16 @@ test_read_unmanaged_unrecognized (void) { NMConnection *connection; NMSettingConnection *s_con; - char *unhandled_spec = NULL; + gs_free char *unhandled_spec = NULL; GError *error = NULL; const char *expected_id = "PigeonNet"; guint64 expected_timestamp = 0; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled-unrecognized", - NULL, NULL, - &unhandled_spec, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled-unrecognized", + NULL, NULL, + &unhandled_spec, + &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -408,16 +408,16 @@ test_read_unrecognized (void) { NMConnection *connection; NMSettingConnection *s_con; - char *unhandled_spec = NULL; + gs_free char *unhandled_spec = NULL; GError *error = NULL; const char *expected_id = "U Can't Touch This"; guint64 expected_timestamp = 0; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-unrecognized", - NULL, NULL, - &unhandled_spec, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-unrecognized", + NULL, NULL, + &unhandled_spec, + &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -452,8 +452,8 @@ test_read_wired_static (const char *file, NMIPAddress *ip6_addr; gboolean success; - connection = connection_from_file (file, NULL, TYPE_ETHERNET, - &unmanaged, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (file, NULL, TYPE_ETHERNET, + &unmanaged, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -527,7 +527,6 @@ test_read_wired_static (const char *file, g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); } - g_free (unmanaged); g_object_unref (connection); } @@ -547,8 +546,8 @@ test_read_wired_static_no_prefix (gconstpointer user_data) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing PREFIX, assuming*"); - connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (file, NULL, TYPE_ETHERNET, NULL, + &error); g_test_assert_expected_messages (); g_assert_no_error (error); g_assert (connection); @@ -584,10 +583,6 @@ test_read_wired_dhcp (void) NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; @@ -595,15 +590,11 @@ test_read_wired_dhcp (void) const char *expected_id = "System test-wired-dhcp"; const char *expected_dhcp_hostname = "foobar"; - connection = connection_from_file (TEST_IFCFG_WIRED_DHCP, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_DHCP, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-dhcp-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP, error->message); @@ -722,10 +713,6 @@ test_read_wired_dhcp (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -740,9 +727,9 @@ test_read_wired_dhcp_plus_ip (void) NMIPAddress *ip6_addr; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", + NULL, TYPE_ETHERNET, NULL, + &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -807,6 +794,38 @@ test_read_wired_dhcp_plus_ip (void) } static void +test_read_wired_shared_plus_ip (void) +{ + NMConnection *connection; + NMSettingIPConfig *s_ip4; + GError *error = NULL; + NMIPAddress *ip4_addr; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-shared-plus-ip", + NULL, TYPE_ETHERNET, NULL, + &error); + nmtst_assert_connection_verifies_without_normalization (connection); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_SHARED); + g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); + + /* IP addresses */ + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.20.30.5"); + + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); + + g_object_unref (connection); +} + +static void test_read_wired_global_gateway (void) { NMConnection *connection; @@ -817,9 +836,9 @@ test_read_wired_global_gateway (void) NMIPAddress *ip4_addr; char *unmanaged = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway", - TYPE_ETHERNET, &unmanaged, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway", + TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway", + TYPE_ETHERNET, &unmanaged, &error); nmtst_assert_connection_verifies_without_normalization (connection); g_assert (unmanaged == NULL); @@ -850,6 +869,37 @@ test_read_wired_global_gateway (void) } static void +test_read_wired_obsolete_gateway_n (void) +{ + NMConnection *connection; + NMSettingIPConfig *s_ip4; + GError *error = NULL; + NMIPAddress *ip4_addr; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-obsolete-gateway-n", + NULL, TYPE_ETHERNET, NULL, + &error); + nmtst_assert_connection_verifies_without_normalization (connection); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + /* IP addresses */ + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); + + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); + + g_object_unref (connection); +} + +static void test_read_wired_never_default (void) { NMConnection *connection; @@ -857,9 +907,9 @@ test_read_wired_never_default (void) NMSettingIPConfig *s_ip6; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default", - TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default", + TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default", + TYPE_ETHERNET, NULL, &error); nmtst_assert_connection_verifies_without_normalization (connection); /* ===== WIRED SETTING ===== */ @@ -892,23 +942,15 @@ test_read_wired_defroute_no (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-defroute-no"; - connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_DEFROUTE_NO, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-defroute-no-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message); @@ -991,10 +1033,6 @@ test_read_wired_defroute_no (void) NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_NEVER_DEFAULT); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1010,23 +1048,15 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-defroute-no-gatewaydev-yes"; - connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, - TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-defroute-no-gatewaydev-yes-read", "failed to read %s: %s", @@ -1117,10 +1147,6 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_NEVER_DEFAULT); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1134,8 +1160,8 @@ test_read_wired_static_routes (void) GError *error = NULL; NMIPRoute *ip4_route; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes", + NULL, TYPE_ETHERNET, NULL, &error); nmtst_assert_connection_verifies_without_normalization (connection); /* ===== CONNECTION SETTING ===== */ @@ -1182,24 +1208,16 @@ test_read_wired_static_routes_legacy (void) NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; NMIPRoute *ip4_route; const char *expected_id = "System test-wired-static-routes-legacy"; - connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-static-routes-legacy-read", @@ -1291,10 +1309,6 @@ test_read_wired_static_routes_legacy (void) g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "7.7.7.7"); g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1306,23 +1320,15 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; NMIPAddress *ip4_addr; - connection = connection_from_file (file, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (file, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-ipv4-manual-read", "failed to read %s: %s", file, error->message); @@ -1402,10 +1408,6 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "3.3.3.3"); g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1420,10 +1422,6 @@ test_read_wired_ipv6_manual (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-ipv6-manual"; @@ -1432,15 +1430,11 @@ test_read_wired_ipv6_manual (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*ignoring manual default route*"); - connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_MANUAL, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_IPV6_MANUAL, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); g_test_assert_expected_messages (); ASSERT (connection != NULL, @@ -1635,10 +1629,6 @@ test_read_wired_ipv6_manual (void) NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1653,25 +1643,17 @@ test_read_wired_ipv6_only (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-ipv6-only"; NMIPAddress *ip6_addr; const char *method; - connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_IPV6_ONLY, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-ipv6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message); @@ -1773,10 +1755,6 @@ test_read_wired_ipv6_only (void) g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "ipsum.org"); g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 2), ==, "dolor.edu"); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1791,24 +1769,16 @@ test_read_wired_dhcp6_only (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-dhcp6-only"; const char *method; - connection = connection_from_file (TEST_IFCFG_WIRED_DHCP6_ONLY, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_DHCP6_ONLY, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-dhcp6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message); @@ -1878,10 +1848,6 @@ test_read_wired_dhcp6_only (void) NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1893,21 +1859,13 @@ test_read_onboot_no (void) NMConnection *connection; NMSettingConnection *s_con; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_ONBOOT_NO, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_ONBOOT_NO, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "onboot-no-read", "failed to read %s: %s", TEST_IFCFG_ONBOOT_NO, error->message); @@ -1932,10 +1890,6 @@ test_read_onboot_no (void) NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1947,22 +1901,13 @@ test_read_noip (void) NMConnection *connection; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_NOIP, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_NOIP, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert (connection); g_assert (nm_connection_verify (connection, &error)); g_assert_no_error (error); @@ -1977,10 +1922,6 @@ test_read_noip (void) g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1996,10 +1937,6 @@ test_read_wired_8021x_peap_mschapv2 (void) NMSetting8021x *s_8021x; NMSetting8021x *tmp_8021x; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_identity = "David Smith"; @@ -2009,15 +1946,11 @@ test_read_wired_8021x_peap_mschapv2 (void) const char *expected_ca_cert_path; const char *read_ca_cert_path; - connection = connection_from_file (TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-8021x-peap-mschapv2-read", "failed to read %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message); @@ -2176,10 +2109,6 @@ test_read_wired_8021x_peap_mschapv2 (void) g_object_unref (tmp_8021x); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2192,25 +2121,16 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags NMConnection *connection; NMSettingWired *s_wired; NMSetting8021x *s_8021x; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *expected_identity = "David Smith"; gboolean success = FALSE; char *dirname, *tmp; - connection = connection_from_file (ifcfg, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (ifcfg, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert_no_error (error); g_assert (connection); @@ -2242,10 +2162,6 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags g_free (dirname); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2260,9 +2176,9 @@ test_read_write_802_1X_subj_matches (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing IEEE_8021X_CA_CERT*peap*"); - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1X-subj-matches", - NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1X-subj-matches", + NULL, TYPE_ETHERNET, NULL, + &error); g_test_assert_expected_messages (); g_assert_no_error (error); g_assert (connection != NULL); @@ -2295,8 +2211,8 @@ test_read_write_802_1X_subj_matches (void) /* re-read the connection for comparison */ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing IEEE_8021X_CA_CERT*peap*"); - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (written, NULL, TYPE_ETHERNET, NULL, + &error); g_test_assert_expected_messages (); unlink (written); g_free (written); @@ -2343,8 +2259,8 @@ test_read_802_1x_ttls_eapgtc (void) * NMSetting8021x::autheap property. */ - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-ttls-eapgtc", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-ttls-eapgtc", + NULL, TYPE_WIRELESS, NULL, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -2374,11 +2290,6 @@ test_read_wired_aliases_good (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System aliasem0"; @@ -2388,15 +2299,11 @@ test_read_wired_aliases_good (void) const char *expected_gateway = "192.168.1.1"; int i, j; - connection = connection_from_file (TEST_IFCFG_ALIASES_GOOD, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_ALIASES_GOOD, + NULL, + TYPE_ETHERNET, + NULL, + &error); ASSERT (connection != NULL, "aliases-good-read", "failed to read %s: %s", TEST_IFCFG_ALIASES_GOOD, error->message); @@ -2485,9 +2392,6 @@ test_read_wired_aliases_good (void) expected_address[i]); } - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2497,24 +2401,15 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) NMConnection *connection; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; NMIPAddress *ip4_addr; - connection = connection_from_file (base, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (base, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_test_assert_expected_messages (); ASSERT (connection != NULL, "aliases-bad-read", "failed to read %s: %s", base, error->message); @@ -2575,9 +2470,6 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) /* Gateway */ g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2610,12 +2502,7 @@ test_read_wifi_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; + NMSettingIPConfig *s_ip4, *s_ip6; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -2627,15 +2514,11 @@ test_read_wifi_open (void) const char *expected_mode = "infrastructure"; const guint32 expected_channel = 1; - connection = connection_from_file (TEST_IFCFG_WIFI_OPEN, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_OPEN, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-open-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN, error->message); @@ -2764,6 +2647,8 @@ test_read_wifi_open (void) TEST_IFCFG_WIFI_OPEN, NM_SETTING_IP4_CONFIG_SETTING_NAME); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip4), ==, 104); + /* Method */ tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, @@ -2772,10 +2657,10 @@ test_read_wifi_open (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert( s_ip6); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip6), ==, 106); + g_object_unref (connection); } @@ -2787,25 +2672,16 @@ test_read_wifi_open_auto (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System blahblah (test-wifi-open-auto)"; const char *expected_mode = "infrastructure"; - connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_AUTO, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_OPEN_AUTO, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-open-auto-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_AUTO, error->message); @@ -2853,10 +2729,6 @@ test_read_wifi_open_auto (void) NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2868,26 +2740,17 @@ test_read_wifi_open_ssid_hex (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; const char *expected_id = "System blahblah (test-wifi-open-ssid-hex)"; const char *expected_ssid = "blahblah"; - connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_HEX, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-open-ssid-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_HEX, error->message); @@ -2941,10 +2804,6 @@ test_read_wifi_open_ssid_hex (void) NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -2952,29 +2811,16 @@ static void test_read_wifi_open_ssid_bad (const char *file, const char *test) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (file, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (file, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection == NULL, test, "unexpected success reading %s", file); g_clear_error (&error); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); } #define TEST_IFCFG_WIFI_OPEN_SSID_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-quoted" @@ -2985,26 +2831,17 @@ test_read_wifi_open_ssid_quoted (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; const char *expected_id = "System foo\"bar\\ (test-wifi-open-ssid-quoted)"; const char *expected_ssid = "foo\"bar\\"; - connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-open-ssid-quoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, error->message); @@ -3058,10 +2895,6 @@ test_read_wifi_open_ssid_quoted (void) NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3075,11 +2908,6 @@ test_read_wifi_wep (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -3093,15 +2921,11 @@ test_read_wifi_wep (void) const char *expected_wep_key0 = "0123456789abcdef0123456789"; NMWepKeyType key_type; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP, error->message); @@ -3316,10 +3140,6 @@ test_read_wifi_wep (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3333,11 +3153,6 @@ test_read_wifi_wep_adhoc (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -3346,15 +3161,11 @@ test_read_wifi_wep_adhoc (void) const char *expected_mode = "adhoc"; const char *expected_wep_key0 = "0123456789abcdef0123456789"; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_ADHOC, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_ADHOC, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_ADHOC, error->message); @@ -3556,10 +3367,6 @@ test_read_wifi_wep_adhoc (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3572,25 +3379,16 @@ test_read_wifi_wep_passphrase (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_wep_key0 = "foobar222blahblah"; NMWepKeyType key_type; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_PASSPHRASE, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-passphrase-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_PASSPHRASE, error->message); @@ -3681,10 +3479,6 @@ test_read_wifi_wep_passphrase (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3697,25 +3491,16 @@ test_read_wifi_wep_40_ascii (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_wep_key0 = "Lorem"; NMWepKeyType key_type; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_40_ASCII, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_40_ASCII, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-40-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_40_ASCII, error->message); @@ -3804,10 +3589,6 @@ test_read_wifi_wep_40_ascii (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3820,25 +3601,16 @@ test_read_wifi_wep_104_ascii (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_wep_key0 = "LoremIpsumSit"; NMWepKeyType key_type; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_104_ASCII, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_104_ASCII, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-104-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_104_ASCII, error->message); @@ -3927,10 +3699,6 @@ test_read_wifi_wep_104_ascii (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -3943,26 +3711,17 @@ test_read_wifi_leap (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System blahblah (test-wifi-leap)"; const char *expected_identity = "Bill Smith"; const char *expected_password = "foobarblah"; - connection = connection_from_file (TEST_IFCFG_WIFI_LEAP, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_LEAP, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-leap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_LEAP, error->message); @@ -4052,10 +3811,6 @@ test_read_wifi_leap (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4068,24 +3823,15 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte NMConnection *connection; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *expected_identity = "Bill Smith"; gboolean success; - connection = connection_from_file (file, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (file, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (connection); @@ -4108,10 +3854,6 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == expected_flags); g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4125,11 +3867,6 @@ test_read_wifi_wpa_psk (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -4152,15 +3889,11 @@ test_read_wifi_wpa_psk (void) gboolean found_proto_wpa = FALSE; gboolean found_proto_rsn = FALSE; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wpa-psk-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK, error->message); @@ -4409,10 +4142,6 @@ test_read_wifi_wpa_psk (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4425,25 +4154,16 @@ test_read_wifi_wpa_psk_2 (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System ipsum (test-wifi-wpa-psk-2)"; const char *expected_psk = "They're really saying I love you. >>`<< \\"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_2, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK_2, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wpa-psk-2-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_2, error->message); @@ -4500,10 +4220,6 @@ test_read_wifi_wpa_psk_2 (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PSK); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4516,25 +4232,16 @@ test_read_wifi_wpa_psk_unquoted (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System blahblah (test-wifi-wpa-psk-unquoted)"; const char *expected_psk = "54336845e2f3f321c4c7"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wpa-psk-unquoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, error->message); @@ -4591,10 +4298,6 @@ test_read_wifi_wpa_psk_unquoted (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PSK); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4604,34 +4307,21 @@ static void test_read_wifi_wpa_psk_unquoted2 (void) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; /* Ensure a quoted 64-character WPA passphrase will fail since passphrases * must be between 8 and 63 ASCII characters inclusive per the WPA spec. */ - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection == NULL, "wifi-wpa-psk-unquoted-read", "unexpected success reading %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2); g_clear_error (&error); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); } #define TEST_IFCFG_WIFI_WPA_PSK_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc" @@ -4644,11 +4334,6 @@ test_read_wifi_wpa_psk_adhoc (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System blahblah (test-wifi-wpa-psk-adhoc)"; @@ -4658,15 +4343,11 @@ test_read_wifi_wpa_psk_adhoc (void) const char *expected_group = "ccmp"; const char *expected_proto = "wpa"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_ADHOC, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wpa-psk-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, error->message); @@ -4805,10 +4486,6 @@ test_read_wifi_wpa_psk_adhoc (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4822,11 +4499,6 @@ test_read_wifi_wpa_psk_hex (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -4835,15 +4507,11 @@ test_read_wifi_wpa_psk_hex (void) const char *expected_key_mgmt = "wpa-psk"; const char *expected_psk = "1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_HEX, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_PSK_HEX, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wpa-psk-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_HEX, error->message); @@ -4947,10 +4615,6 @@ test_read_wifi_wpa_psk_hex (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -4967,24 +4631,16 @@ test_read_wifi_wpa_eap_tls (void) NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp, *password; const char *expected_identity = "Bill Smith"; const char *expected_privkey_password = "test1"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TLS, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_EAP_TLS, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wifi-wpa-eap-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message); @@ -5088,10 +4744,6 @@ test_read_wifi_wpa_eap_tls (void) expected_privkey_password, NM_SETTING_802_1X_PRIVATE_KEY); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5107,24 +4759,16 @@ test_read_wifi_wpa_eap_ttls_tls (void) NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp, *password; const char *expected_identity = "Chuck Shumer"; const char *expected_privkey_password = "test1"; - connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NULL, + TYPE_WIRELESS, + &unmanaged, + &error); ASSERT (connection != NULL, "wifi-wpa-eap-ttls-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message); @@ -5247,10 +4891,6 @@ test_read_wifi_wpa_eap_ttls_tls (void) NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5263,22 +4903,14 @@ test_read_wifi_dynamic_wep_leap (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE, success; + gboolean success; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (connection); @@ -5319,10 +4951,6 @@ test_read_wifi_dynamic_wep_leap (void) g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "bill smith"); g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz"); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5338,25 +4966,17 @@ test_read_wifi_wep_eap_ttls_chap (void) NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_password = "foobar baz"; const char *expected_identity = "David Smith"; const char *expected_key_mgmt = "ieee8021x"; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NULL, + TYPE_WIRELESS, + &unmanaged, + &error); ASSERT (connection != NULL, "wifi-wep-eap-ttls-chap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message); @@ -5480,10 +5100,6 @@ test_read_wifi_wep_eap_ttls_chap (void) NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PASSWORD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5496,8 +5112,8 @@ test_read_wifi_hidden (void) gboolean success; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-hidden", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-hidden", + NULL, TYPE_WIRELESS, NULL, &error); g_assert_no_error (error); g_assert (connection); @@ -5584,8 +5200,8 @@ test_write_wifi_hidden (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (testfile, NULL, TYPE_WIRELESS, + NULL, &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); @@ -5610,8 +5226,8 @@ test_read_wifi_band_a (void) gboolean success; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a", + NULL, TYPE_WIRELESS, NULL, &error); g_assert_no_error (error); g_assert (connection); @@ -5698,8 +5314,8 @@ test_write_wifi_band_a (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (testfile, NULL, TYPE_WIRELESS, + NULL, &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); @@ -5721,10 +5337,11 @@ test_read_wifi_band_a_channel_mismatch (void) NMConnection *connection; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch", + NULL, TYPE_WIRELESS, NULL, &error); g_assert (connection == NULL); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_clear_error (&error); } static void @@ -5733,10 +5350,11 @@ test_read_wifi_band_bg_channel_mismatch (void) NMConnection *connection; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch", + NULL, TYPE_WIRELESS, NULL, &error); g_assert (connection == NULL); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_clear_error (&error); } #define TEST_IFCFG_WIRED_QETH_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-qeth-static" @@ -5749,10 +5367,6 @@ test_read_wired_qeth_static (void) NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-qeth-static"; @@ -5762,15 +5376,11 @@ test_read_wired_qeth_static (void) const char *expected_channel2 = "0.0.0602"; const char * const *subchannels; - connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_QETH_STATIC, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); ASSERT (connection != NULL, "wired-qeth-static-read", "failed to read %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message); @@ -5902,10 +5512,6 @@ test_read_wired_qeth_static (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5918,10 +5524,6 @@ test_read_wired_ctc_static (void) NMSettingConnection *s_con; NMSettingWired *s_wired; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-ctc-static"; @@ -5930,15 +5532,11 @@ test_read_wired_ctc_static (void) const char * const *subchannels; gboolean success; - connection = connection_from_file (TEST_IFCFG_WIRED_CTC_STATIC, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIRED_CTC_STATIC, + NULL, + TYPE_ETHERNET, + &unmanaged, + &error); g_assert_no_error (error); g_assert (connection); @@ -5974,10 +5572,6 @@ test_read_wired_ctc_static (void) g_assert (tmp != NULL); g_assert_cmpstr (tmp, ==, "0"); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -5990,25 +5584,16 @@ test_read_wifi_wep_no_keys (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; const char *expected_id = "System foobar (test-wifi-wep-no-keys)"; NMWepKeyType key_type; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_NO_KEYS, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_NO_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &error); ASSERT (connection != NULL, "wifi-wep-no-keys-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message); @@ -6086,10 +5671,6 @@ test_read_wifi_wep_no_keys (void) NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -6100,24 +5681,16 @@ test_read_permissions (void) { NMConnection *connection; NMSettingConnection *s_con; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE, success; + gboolean success; GError *error = NULL; guint32 num; const char *tmp; - connection = connection_from_file (TEST_IFCFG_PERMISSIONS, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_PERMISSIONS, + NULL, + TYPE_ETHERNET, + NULL, + &error); ASSERT (connection != NULL, "permissions-read", "failed to read %s: %s", TEST_IFCFG_PERMISSIONS, error->message); @@ -6159,10 +5732,6 @@ test_read_permissions (void) ASSERT (strcmp (tmp, "johnny5") == 0, "permissions-verify-permissions", "unexpected permission #3"); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -6174,25 +5743,16 @@ test_read_wifi_wep_agent_keys (void) NMConnection *connection; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; NMWepKeyType key_type; gboolean success; NMSettingSecretFlags flags; - connection = connection_from_file (TEST_IFCFG_WIFI_WEP_AGENT_KEYS, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_WIFI_WEP_AGENT_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert (connection != NULL); success = nm_connection_verify (connection, &error); @@ -6223,10 +5783,6 @@ test_read_wifi_wep_agent_keys (void) flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec); g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -6256,11 +5812,7 @@ test_write_wired_static (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -6294,6 +5846,7 @@ test_write_wired_static (void) NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 204, NULL); addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); @@ -6319,6 +5872,7 @@ test_write_wired_static (void) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 206, NULL); /* Add addresses */ @@ -6378,15 +5932,11 @@ test_write_wired_static (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -6406,16 +5956,16 @@ test_write_wired_static (void) nm_setting_ip_config_remove_dns_search (reread_s_ip4, 3); nm_setting_ip_config_remove_dns_search (reread_s_ip4, 2); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip4), ==, 204); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip6), ==, 206); + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "wired-static-write", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); + route6file = utils_get_route6_path (testfile); + unlink (route6file); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -6434,11 +5984,6 @@ test_write_wired_dhcp (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -6500,15 +6045,11 @@ test_write_wired_dhcp (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -6521,10 +6062,6 @@ test_write_wired_dhcp (void) "wired-dhcp-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -6537,9 +6074,9 @@ test_write_wired_dhcp_plus_ip (void) GError *error = NULL; gboolean success = FALSE; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", + NULL, TYPE_ETHERNET, NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); @@ -6553,8 +6090,8 @@ test_write_wired_dhcp_plus_ip (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (written, NULL, TYPE_ETHERNET, NULL, + &error); unlink (written); g_free (written); @@ -6583,9 +6120,9 @@ test_read_write_wired_dhcp_send_hostname (void) GError *error = NULL; gboolean success = FALSE; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-send-hostname", - NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-send-hostname", + NULL, TYPE_ETHERNET, NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); @@ -6613,8 +6150,8 @@ test_read_write_wired_dhcp_send_hostname (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (written, NULL, TYPE_ETHERNET, NULL, + &error); unlink (written); g_free (written); @@ -6657,11 +6194,7 @@ test_write_wired_static_ip6_only (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -6729,15 +6262,11 @@ test_write_wired_static_ip6_only (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -6749,13 +6278,7 @@ test_write_wired_static_ip6_only (void) ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "wired-static-ip6-only-write", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -6786,7 +6309,6 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) GError *error = NULL; char *testfile = NULL; char *id = NULL; - gboolean ignore_error = FALSE; char *written_ifcfg_gateway; const char *gateway6 = user_data; @@ -6854,13 +6376,11 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - NULL, NULL, - NULL, NULL, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert_no_error (error); g_assert (reread); g_assert (nm_connection_verify (reread, &error)); @@ -6909,28 +6429,18 @@ test_read_write_static_routes_legacy (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; char *testfile = NULL; - char *keyfile = NULL; - char *keyfile2 = NULL; - char *routefile = NULL; char *routefile2 = NULL; - char *route6file = NULL; char *route6file2 = NULL; - gboolean ignore_error = FALSE; gboolean success; GError *error = NULL; const char *tmp; - connection = connection_from_file (TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NULL, + TYPE_ETHERNET, + NULL, + &error); ASSERT (connection != NULL, "read-write-static-routes-legacy-read", "failed to read %s: %s", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, error->message); @@ -7011,17 +6521,15 @@ test_read_write_static_routes_legacy (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile2, - &routefile2, - &route6file2, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); + routefile2 = utils_get_route_path (testfile); unlink (routefile2); + route6file2 = utils_get_route6_path (testfile); unlink (route6file2); ASSERT (reread != NULL, @@ -7037,12 +6545,7 @@ test_read_write_static_routes_legacy (void) "read-write-static-routes-legacy-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (keyfile2); - g_free (routefile); g_free (routefile2); - g_free (route6file); g_free (route6file2); g_object_unref (connection); g_object_unref (reread); @@ -7069,11 +6572,7 @@ test_write_wired_static_routes (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -7164,22 +6663,17 @@ test_write_wired_static_routes (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, "wired-static-routes-write-reread", "failed to read %s: %s", testfile, error->message); - ASSERT (routefile != NULL, - "wired-static-routes-write-reread", "expected routefile for '%s'", testfile); + routefile = utils_get_route_path (testfile); unlink (routefile); ASSERT (nm_connection_verify (reread, &error), @@ -7189,10 +6683,7 @@ test_write_wired_static_routes (void) "wired-static-routes-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -7211,11 +6702,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -7295,22 +6782,17 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, "wired-dhcp-8021x-peap-mschapv2write-reread", "failed to read %s: %s", testfile, error->message); - ASSERT (keyfile != NULL, - "wired-dhcp-8021x-peap-mschapv2write-reread", "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); ASSERT (nm_connection_verify (reread, &error), @@ -7320,10 +6802,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) "wired-dhcp-8021x-peap-mschapv2write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -7365,11 +6844,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; const char *pw; char *tmp; @@ -7479,17 +6954,13 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - g_assert (keyfile != NULL); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); g_assert (reread != NULL); @@ -7555,10 +7026,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, g_free (tmp); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -7581,11 +7049,6 @@ test_write_wired_aliases (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; shvarFile *ifcfg; int i, j; @@ -7679,15 +7142,11 @@ test_write_wired_aliases (void) "wired-aliases-write", "saving failed to delete unused ifcfg-alias0:5"); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); unlink (TEST_SCRATCH_ALIAS_BASE ":2"); unlink (TEST_SCRATCH_ALIAS_BASE ":3"); @@ -7743,9 +7202,6 @@ test_write_wired_aliases (void) g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); g_free (testfile); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -7861,8 +7317,8 @@ test_write_gateway (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (testfile, NULL, TYPE_WIRELESS, + NULL, &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); @@ -7892,11 +7348,6 @@ test_write_wifi_open (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; const char *bssid = "11:22:33:44:55:66"; @@ -7973,15 +7424,11 @@ test_write_wifi_open (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); /* Now make sure that the ESSID item isn't double-quoted (rh #606518) */ @@ -8011,10 +7458,6 @@ test_write_wifi_open (void) "wifi-open-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8032,11 +7475,6 @@ test_write_wifi_open_hex_ssid (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const unsigned char ssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd }; @@ -8103,15 +7541,11 @@ test_write_wifi_open_hex_ssid (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -8124,10 +7558,6 @@ test_write_wifi_open_hex_ssid (void) "wifi-open-hex-ssid-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8146,11 +7576,7 @@ test_write_wifi_wep (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; struct stat statbuf; @@ -8232,27 +7658,20 @@ test_write_wifi_wep (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wep-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-wep-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-wep-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-wep-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8265,10 +7684,7 @@ test_write_wifi_wep (void) "wifi-wep-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8287,11 +7703,7 @@ test_write_wifi_wep_adhoc (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; struct stat statbuf; @@ -8379,27 +7791,20 @@ test_write_wifi_wep_adhoc (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wep-adhoc-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-wep-adhoc-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8412,10 +7817,7 @@ test_write_wifi_wep_adhoc (void) "wifi-wep-adhoc-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8434,11 +7836,7 @@ test_write_wifi_wep_passphrase (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; struct stat statbuf; @@ -8518,27 +7916,20 @@ test_write_wifi_wep_passphrase (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wep-passphrase-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-wep-passphrase-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8551,10 +7942,7 @@ test_write_wifi_wep_passphrase (void) "wifi-wep-passphrase-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8573,11 +7961,7 @@ test_write_wifi_wep_40_ascii (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah40"; struct stat statbuf; @@ -8659,27 +8043,20 @@ test_write_wifi_wep_40_ascii (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wep-40-ascii-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-wep-40-ascii-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8692,10 +8069,7 @@ test_write_wifi_wep_40_ascii (void) "wifi-wep-40-ascii-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8714,11 +8088,7 @@ test_write_wifi_wep_104_ascii (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah104"; struct stat statbuf; @@ -8800,27 +8170,20 @@ test_write_wifi_wep_104_ascii (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wep-104-ascii-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-wep-104-ascii-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8833,10 +8196,7 @@ test_write_wifi_wep_104_ascii (void) "wifi-wep-104-ascii-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8855,11 +8215,7 @@ test_write_wifi_leap (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; struct stat statbuf; @@ -8938,27 +8294,20 @@ test_write_wifi_leap (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-leap-write-reread", "expected keyfile for '%s'", testfile); - + keyfile = utils_get_keys_path (testfile); ASSERT (stat (keyfile, &statbuf) == 0, "wifi-leap-write-reread", "couldn't stat() '%s'", keyfile); ASSERT (S_ISREG (statbuf.st_mode), "wifi-leap-write-reread", "keyfile '%s' wasn't a normal file", keyfile); ASSERT ((statbuf.st_mode & 0077) == 0, "wifi-leap-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); - unlink (keyfile); ASSERT (reread != NULL, @@ -8971,10 +8320,7 @@ test_write_wifi_leap (void) "wifi-leap-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -8993,11 +8339,7 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -9075,21 +8417,17 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); g_assert_no_error (error); /* No key should be written out since the secret is not system owned */ - g_assert (keyfile); + keyfile = utils_get_keys_path (testfile); g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE); g_assert (reread); @@ -9105,10 +8443,7 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9132,11 +8467,7 @@ test_write_wifi_wpa_psk (const char *name, gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -9229,22 +8560,17 @@ test_write_wifi_wpa_psk (const char *name, nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - tmp = g_strdup_printf ("%s-reread", test_name); - ASSERT (keyfile != NULL, - tmp, "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); + tmp = g_strdup_printf ("%s-reread", test_name); ASSERT (reread != NULL, tmp, "failed to read %s: %s", testfile, error->message); @@ -9256,10 +8582,7 @@ test_write_wifi_wpa_psk (const char *name, test_name, "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9278,11 +8601,7 @@ test_write_wifi_wpa_psk_adhoc (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; NMIPAddress *addr; @@ -9376,19 +8695,14 @@ test_write_wifi_wpa_psk_adhoc (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wpa-psk-adhoc-write-reread", "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); ASSERT (reread != NULL, @@ -9401,10 +8715,7 @@ test_write_wifi_wpa_psk_adhoc (void) "wifi-wpa-psk-adhoc-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9424,11 +8735,7 @@ test_write_wifi_wpa_eap_tls (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -9540,19 +8847,14 @@ test_write_wifi_wpa_eap_tls (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); - ASSERT (keyfile != NULL, - "wifi-wpa-eap-tls-write-reread", "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); ASSERT (reread != NULL, @@ -9565,10 +8867,7 @@ test_write_wifi_wpa_eap_tls (void) "wifi-wpa-eap-tls-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9588,11 +8887,7 @@ test_write_wifi_wpa_eap_ttls_tls (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -9722,22 +9017,17 @@ test_write_wifi_wpa_eap_ttls_tls (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, "wifi-wpa-eap-ttls-tls-write-reread", "failed to read %s: %s", testfile, error->message); - ASSERT (keyfile != NULL, - "wifi-wpa-eap-ttls-tls-write-reread", "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); ASSERT (nm_connection_verify (reread, &error), @@ -9747,10 +9037,7 @@ test_write_wifi_wpa_eap_ttls_tls (void) "wifi-wpa-eap-ttls-tls-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9770,11 +9057,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -9876,22 +9159,17 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, "wifi-wpa-eap-ttls-mschapv2-write-reread", "failed to read %s: %s", testfile, error->message); - ASSERT (keyfile != NULL, - "wifi-wpa-eap-ttls-mschapv2-write-reread", "expected keyfile for '%s'", testfile); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); ASSERT (nm_connection_verify (reread, &error), @@ -9901,10 +9179,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) "wifi-wpa-eap-ttls-mschapv2-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -9923,11 +9198,7 @@ test_write_wifi_wpa_then_open (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; @@ -10018,15 +9289,11 @@ test_write_wifi_wpa_then_open (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (reread); @@ -10036,18 +9303,13 @@ test_write_wifi_wpa_then_open (void) success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); g_assert (success); - g_free (unmanaged); - unmanaged = NULL; - g_free (routefile); - routefile = NULL; - g_free (route6file); - route6file = NULL; g_object_unref (reread); /* Now change the connection to open and recheck */ nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); /* Write it back out */ + keyfile = utils_get_keys_path (testfile); success = writer_update_connection (connection, TEST_SCRATCH_DIR "/network-scripts/", testfile, @@ -10064,22 +9326,18 @@ test_write_wifi_wpa_then_open (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read it for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); /* No keyfile since it's an open connection this time */ - g_assert (keyfile); + keyfile = utils_get_keys_path (testfile); g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE); success = nm_connection_verify (reread, &error); @@ -10090,10 +9348,7 @@ test_write_wifi_wpa_then_open (void) unlink (testfile); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (reread); g_object_unref (connection); @@ -10113,11 +9368,7 @@ test_write_wifi_wpa_then_wep_with_perms (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; char **perms; const char *ssid_data = "SomeSSID"; @@ -10214,15 +9465,11 @@ test_write_wifi_wpa_then_wep_with_perms (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (reread); @@ -10232,12 +9479,6 @@ test_write_wifi_wpa_then_wep_with_perms (void) success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); g_assert (success); - g_free (unmanaged); - unmanaged = NULL; - g_free (routefile); - routefile = NULL; - g_free (route6file); - route6file = NULL; g_object_unref (reread); /* Now change the connection to WEP and recheck */ @@ -10251,6 +9492,7 @@ test_write_wifi_wpa_then_wep_with_perms (void) nm_setting_wireless_security_set_wep_key (s_wsec, 0, "abraka dabra"); /* Write it back out */ + keyfile = utils_get_keys_path (testfile); success = writer_update_connection (connection, TEST_SCRATCH_DIR "/network-scripts/", testfile, @@ -10266,15 +9508,11 @@ test_write_wifi_wpa_then_wep_with_perms (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read it for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (reread); @@ -10289,14 +9527,12 @@ test_write_wifi_wpa_then_wep_with_perms (void) ASSERT (success, "test_write_wifi_wpa_then_wep_with_perms", "failed to compare connections"); + keyfile = utils_get_keys_path (testfile); unlink (keyfile); unlink (testfile); + g_free (keyfile); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (reread); g_object_unref (connection); @@ -10317,11 +9553,7 @@ test_write_wifi_dynamic_wep_leap (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GBytes *ssid; const char *ssid_data = "blahblah"; shvarFile *ifcfg; @@ -10409,18 +9641,15 @@ test_write_wifi_dynamic_wep_leap (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); g_assert_no_error (error); g_assert (reread); - g_assert (keyfile); + + keyfile = utils_get_keys_path (testfile); unlink (keyfile); success = nm_connection_verify (reread, &error); @@ -10449,10 +9678,7 @@ test_write_wifi_dynamic_wep_leap (void) unlink (testfile); g_free (testfile); - g_free (unmanaged); g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -10471,11 +9697,7 @@ test_write_wired_qeth_dhcp (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -10546,15 +9768,11 @@ test_write_wired_qeth_dhcp (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -10566,13 +9784,7 @@ test_write_wired_qeth_dhcp (void) ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "wired-qeth-dhcp-write", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -10592,11 +9804,7 @@ test_write_wired_ctc_dhcp (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; shvarFile *ifcfg; char *tmp; @@ -10680,15 +9888,11 @@ test_write_wired_ctc_dhcp (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); g_assert (reread); @@ -10699,13 +9903,7 @@ test_write_wired_ctc_dhcp (void) success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); g_assert (success); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -10724,11 +9922,7 @@ test_write_permissions (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -10791,15 +9985,11 @@ test_write_permissions (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -10811,13 +10001,7 @@ test_write_permissions (void) ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "permissions-write", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -10839,11 +10023,7 @@ test_write_wifi_wep_agent_keys (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); g_assert (connection != NULL); @@ -10919,15 +10099,11 @@ test_write_wifi_wep_agent_keys (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &error); unlink (testfile); g_assert_no_error (error); @@ -10951,13 +10127,7 @@ test_write_wifi_wep_agent_keys (void) success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); g_assert (success); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -11031,6 +10201,7 @@ test_write_wired_pppoe (void) "wired-pppoe-write", "unexpected success writing connection to disk"); g_object_unref (connection); + g_clear_error (&error); } static void @@ -11093,6 +10264,7 @@ test_write_vpn (void) "vpn-write", "unexpected success writing connection to disk"); g_object_unref (connection); + g_clear_error (&error); } static void @@ -11175,6 +10347,7 @@ test_write_mobile_broadband (gboolean gsm) "mobile-broadband-write", "unexpected success writing connection to disk"); g_object_unref (connection); + g_clear_error (&error); } #define TEST_IFCFG_BRIDGE_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-main" @@ -11186,22 +10359,13 @@ test_read_bridge_main (void) NMSettingBridge *s_bridge; const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_BRIDGE_MAIN, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_BRIDGE_MAIN, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert (connection); g_assert (nm_connection_verify (connection, &error)); g_assert_no_error (error); @@ -11212,7 +10376,7 @@ test_read_bridge_main (void) s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); - g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 0); + g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 2); g_assert (nm_setting_bridge_get_stp (s_bridge)); g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7); @@ -11224,10 +10388,6 @@ test_read_bridge_main (void) g_assert (mac); g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -11246,11 +10406,6 @@ test_write_bridge_main (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); g_assert (connection); @@ -11318,15 +10473,11 @@ test_write_bridge_main (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_BRIDGE, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_BRIDGE, + NULL, + &error); unlink (testfile); g_assert (reread); @@ -11335,10 +10486,6 @@ test_write_bridge_main (void) g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -11351,23 +10498,14 @@ test_read_bridge_component (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingBridgePort *s_port; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; gboolean success; - connection = connection_from_file (TEST_IFCFG_BRIDGE_COMPONENT, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_BRIDGE_COMPONENT, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -11385,10 +10523,6 @@ test_read_bridge_component (void) g_assert_cmpuint (nm_setting_bridge_port_get_priority (s_port), ==, 28); g_assert_cmpuint (nm_setting_bridge_port_get_path_cost (s_port), ==, 100); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -11406,11 +10540,7 @@ test_write_bridge_component (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); g_assert (connection); @@ -11466,15 +10596,11 @@ test_write_bridge_component (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); g_assert (reread); @@ -11484,13 +10610,7 @@ test_write_bridge_component (void) g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -11501,22 +10621,13 @@ test_read_bridge_missing_stp (void) { NMConnection *connection; NMSettingBridge *s_bridge; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-missing-stp", - NULL, - TYPE_BRIDGE, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-missing-stp", + NULL, + TYPE_BRIDGE, + NULL, + &error); g_assert (connection); g_assert (nm_connection_verify (connection, &error)); g_assert_no_error (error); @@ -11529,10 +10640,6 @@ test_read_bridge_missing_stp (void) g_assert (s_bridge); g_assert (nm_setting_bridge_get_stp (s_bridge) == FALSE); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -11542,31 +10649,18 @@ static void test_read_vlan_interface (void) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; NMSettingVlan *s_vlan; guint32 from = 0, to = 0; - connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_VLAN_INTERFACE, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan43"); @@ -11613,30 +10707,17 @@ static void test_read_vlan_only_vlan_id (void) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; NMSettingVlan *s_vlan; - connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_VLAN_ONLY_VLANID, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_assert (nm_connection_get_interface_name (connection) == NULL); @@ -11655,30 +10736,17 @@ static void test_read_vlan_only_device (void) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; NMSettingVlan *s_vlan; - connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_DEVICE, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_VLAN_ONLY_DEVICE, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0.9"); @@ -11698,9 +10766,9 @@ test_read_vlan_physdev (void) GError *error = NULL; NMSettingVlan *s_vlan; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-physdev", - NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-physdev", + NULL, TYPE_ETHERNET, NULL, + &error); g_assert_no_error (error); g_assert (connection); g_assert (nm_connection_verify (connection, &error)); @@ -11720,24 +10788,15 @@ static void test_write_vlan (void) { NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; char *written = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; gboolean success = FALSE; - connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, - NULL, - TYPE_VLAN, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_VLAN_INTERFACE, + NULL, + TYPE_VLAN, + NULL, + &error); g_assert (connection != NULL); success = writer_new_connection (connection, @@ -11749,46 +10808,25 @@ test_write_vlan (void) unlink (written); g_free (written); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); + g_object_unref (connection); } static void test_write_vlan_only_vlanid (void) { NMConnection *connection, *reread; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; char *written = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; gboolean success = FALSE; - connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, - NULL, - TYPE_VLAN, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_VLAN_ONLY_VLANID, + NULL, + TYPE_VLAN, + NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); - g_free (unmanaged); - unmanaged = NULL; - g_free (keyfile); - keyfile = NULL; - g_free (routefile); - routefile = NULL; - g_free (route6file); - route6file = NULL; - success = writer_new_connection (connection, TEST_SCRATCH_DIR "/network-scripts/", &written, @@ -11799,21 +10837,13 @@ test_write_vlan_only_vlanid (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (written, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (written, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (written); g_free (written); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_assert_no_error (error); g_assert (reread != NULL); @@ -11842,11 +10872,6 @@ test_write_ethernet_missing_ipv6 (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); g_assert (connection); @@ -11907,15 +10932,11 @@ test_write_ethernet_missing_ipv6 (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -11941,10 +10962,6 @@ test_write_ethernet_missing_ipv6 (void) "ethernet-missing-ipv6", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -11955,11 +10972,12 @@ test_read_ibft_ignored (void) NMConnection *connection; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft", - NULL, TYPE_ETHERNET, - NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft", + NULL, TYPE_ETHERNET, + NULL, &error); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (connection == NULL); + g_clear_error (&error); } #define TEST_IFCFG_BOND_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-main" @@ -11969,22 +10987,13 @@ test_read_bond_main (void) { NMConnection *connection; NMSettingBond *s_bond; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_BOND_MAIN, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_BOND_MAIN, + NULL, + TYPE_ETHERNET, + NULL, + &error); ASSERT (connection != NULL, "bond-main-read", "unexpected failure reading %s", TEST_IFCFG_BOND_MAIN); @@ -12007,10 +11016,6 @@ test_read_bond_main (void) "bond-main", "failed to verify %s: miimon=%s does not match 100", TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON)); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -12029,11 +11034,6 @@ test_write_bond_main (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -12100,15 +11100,11 @@ test_write_bond_main (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_BOND, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_BOND, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -12121,10 +11117,6 @@ test_write_bond_main (void) "bond-main-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -12136,22 +11128,13 @@ test_read_bond_slave (void) { NMConnection *connection; NMSettingConnection *s_con; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_BOND_SLAVE, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_BOND_SLAVE, + NULL, + TYPE_ETHERNET, + NULL, + &error); g_test_assert_expected_messages (); ASSERT (connection != NULL, @@ -12173,10 +11156,6 @@ test_read_bond_slave (void) "bond-slave-read", "failed to verify %s: slave-type is not bond", TEST_IFCFG_BOND_SLAVE); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -12193,11 +11172,7 @@ test_write_bond_slave (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -12245,15 +11220,11 @@ test_write_bond_slave (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -12265,13 +11236,7 @@ test_write_bond_slave (void) ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "bond-slave-write", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); @@ -12285,24 +11250,16 @@ test_read_infiniband (void) NMConnection *connection; NMSettingInfiniband *s_infiniband; char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; GError *error = NULL; const char *mac; char expected_mac_address[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; const char *transport_mode; - connection = connection_from_file (TEST_IFCFG_INFINIBAND, - NULL, - TYPE_INFINIBAND, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + connection = connection_from_file_test (TEST_IFCFG_INFINIBAND, + NULL, + TYPE_INFINIBAND, + &unmanaged, + &error); ASSERT (connection != NULL, "infiniband-read", "failed to read %s: %s", TEST_IFCFG_INFINIBAND, error->message); @@ -12346,10 +11303,6 @@ test_read_infiniband (void) NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -12369,11 +11322,6 @@ test_write_infiniband (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -12443,15 +11391,11 @@ test_write_infiniband (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_INFINIBAND, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_INFINIBAND, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -12464,10 +11408,6 @@ test_write_infiniband (void) "infiniband-write", "written and re-read connection weren't the same."); g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); g_object_unref (reread); } @@ -12479,22 +11419,13 @@ test_read_bond_slave_ib (void) { NMConnection *connection; NMSettingConnection *s_con; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - - connection = connection_from_file (TEST_IFCFG_BOND_SLAVE_IB, - NULL, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_BOND_SLAVE_IB, + NULL, + NULL, + NULL, + &error); g_test_assert_expected_messages(); ASSERT (connection != NULL, @@ -12516,10 +11447,6 @@ test_read_bond_slave_ib (void) "bond-slave-read-ib", "failed to verify %s: slave-type is not bond", TEST_IFCFG_BOND_SLAVE_IB); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -12535,11 +11462,7 @@ test_write_bond_slave_ib (void) gboolean success; GError *error = NULL; char *testfile = NULL; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; char *route6file = NULL; - gboolean ignore_error = FALSE; connection = nm_simple_connection_new (); @@ -12588,15 +11511,11 @@ test_write_bond_slave_ib (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + NULL, + NULL, + &error); unlink (testfile); ASSERT (reread != NULL, @@ -12608,18 +11527,43 @@ test_write_bond_slave_ib (void) ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "bond-slave-write-ib", "written and re-read connection weren't the same."); - if (route6file) - unlink (route6file); - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); g_free (route6file); g_object_unref (connection); g_object_unref (reread); } +static void +test_read_bond_opts_mode_numeric (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingBond *s_bond; + gboolean success; + GError *error = NULL; + + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-mode-numeric", + NULL, TYPE_ETHERNET, NULL, &error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "bond0"); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); + + s_bond = nm_connection_get_setting_bond (connection); + g_assert (s_bond); + g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE), ==, "802.3ad"); + + g_object_unref (connection); +} + #define DCB_ALL_FLAGS (NM_SETTING_DCB_FLAG_ENABLE | \ NM_SETTING_DCB_FLAG_ADVERTISE | \ NM_SETTING_DCB_FLAG_WILLING) @@ -12639,8 +11583,8 @@ test_read_dcb_basic (void) guint expected_traffic_classes[8] = { 7, 6, 5, 4, 3, 2, 1, 0 }; gboolean expected_pfcs[8] = { TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -12698,7 +11642,7 @@ test_write_dcb_basic (void) NMSettingDcb *s_dcb; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - gboolean success, ignore_error; + gboolean success; guint i; char *uuid, *testfile; const guint group_ids[8] = { 4, 0xF, 6, 0xF, 1, 7, 3, 0xF }; @@ -12770,13 +11714,11 @@ test_write_dcb_basic (void) g_assert (testfile); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - NULL, NULL, - NULL, NULL, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); g_assert_no_error (error); @@ -12797,8 +11739,8 @@ test_read_dcb_default_app_priorities (void) NMSettingDcb *s_dcb; gboolean success; - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-default-app-priorities", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-default-app-priorities", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -12828,13 +11770,14 @@ test_read_dcb_bad_booleans (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_STRICT value*not all 0s and 1s*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid boolean digit")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12845,13 +11788,14 @@ test_read_dcb_short_booleans (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_STRICT value*8 characters*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "boolean array must be 8 characters")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12862,13 +11806,14 @@ test_read_dcb_bad_uints (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_UP2TC value*not 0 - 7*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid uint digit")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12879,13 +11824,14 @@ test_read_dcb_short_uints (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_UP2TC value*8 characters*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "uint array must be 8 characters")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12896,13 +11842,14 @@ test_read_dcb_bad_percent (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_PCT percentage value*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid percent element")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12913,13 +11860,14 @@ test_read_dcb_short_percent (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_PCT percentage list value*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "percent array must be 8 elements")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12930,13 +11878,14 @@ test_read_dcb_pgpct_not_100 (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_PCT percentages do not equal 100*"); - connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100", + NULL, TYPE_ETHERNET, NULL, &error); g_test_assert_expected_messages (); g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid percentage sum")); g_assert (connection == NULL); + g_clear_error (&error); } static void @@ -12950,7 +11899,7 @@ test_read_fcoe_mode (gconstpointer user_data) char *file; file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-fcoe-%s", expected_mode); - connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (file, NULL, TYPE_ETHERNET, NULL, &error); g_free (file); g_assert_no_error (error); g_assert (connection); @@ -12978,7 +11927,7 @@ test_write_fcoe_mode (gconstpointer user_data) NMSettingDcb *s_dcb; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - gboolean success, ignore_error; + gboolean success; char *uuid, *testfile; connection = nm_simple_connection_new (); @@ -13040,13 +11989,11 @@ test_write_fcoe_mode (gconstpointer user_data) } /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_ETHERNET, - NULL, NULL, - NULL, NULL, - &error, - &ignore_error); + reread = connection_from_file_test (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &error); unlink (testfile); g_assert_no_error (error); @@ -13069,8 +12016,8 @@ test_read_team_master (void) GError *error = NULL; const char *expected_config = "{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }"; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); @@ -13181,8 +12128,8 @@ test_write_team_master (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (testfile, NULL, TYPE_ETHERNET, + NULL, &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); @@ -13208,8 +12155,8 @@ test_read_team_port (void) GError *error = NULL; const char *expected_config = "{ \"p4p1\": { \"prio\": -10, \"sticky\": true } }"; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); @@ -13294,6 +12241,7 @@ test_write_team_port (void) val = svGetValue (f, "TEAM_PORT_CONFIG", TRUE); g_assert (val); g_assert_cmpstr (val, ==, escaped_expected_config); + g_free (val); val = svGetValue (f, "TEAM_MASTER", TRUE); g_assert (val); g_assert_cmpstr (val, ==, "team0"); @@ -13304,8 +12252,8 @@ test_write_team_port (void) nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, NULL, NULL, NULL, &error, NULL); + reread = connection_from_file_test (testfile, NULL, TYPE_ETHERNET, + NULL, &error); unlink (testfile); g_assert_no_error (error); g_assert (reread); @@ -13329,8 +12277,8 @@ test_read_team_port_empty_config (void) gboolean success; GError *error = NULL; - connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-empty-config", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-empty-config", + NULL, TYPE_ETHERNET, NULL, &error); g_assert_no_error (error); g_assert (connection); @@ -13475,8 +12423,8 @@ test_read_vlan_trailing_spaces (void) g_assert (strstr (contents, "DEVICE=\"vlan201\" \n")); g_free (contents); - connection = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, - NULL, NULL, NULL, &error, NULL); + connection = connection_from_file_test (testfile, NULL, TYPE_ETHERNET, NULL, + &error); g_assert_no_error (error); g_assert (connection != NULL); @@ -13513,7 +12461,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); g_test_add_func (TPATH "svUnescape", test_svUnescape); g_test_add_func (TPATH "vlan-trailing-spaces", test_read_vlan_trailing_spaces); @@ -13536,8 +12484,10 @@ int main (int argc, char **argv) test_read_wired_static (TEST_IFCFG_WIRED_STATIC_BOOTPROTO, "System test-wired-static-bootproto", FALSE); test_read_wired_dhcp (); g_test_add_func (TPATH "dhcp-plus-ip", test_read_wired_dhcp_plus_ip); + g_test_add_func (TPATH "shared-plus-ip", test_read_wired_shared_plus_ip); g_test_add_func (TPATH "dhcp-send-hostname", test_read_write_wired_dhcp_send_hostname); g_test_add_func (TPATH "global-gateway", test_read_wired_global_gateway); + g_test_add_func (TPATH "obsolete-gateway-n", test_read_wired_obsolete_gateway_n); g_test_add_func (TPATH "never-default", test_read_wired_never_default); test_read_wired_defroute_no (); test_read_wired_defroute_no_gatewaydev_yes (); @@ -13706,6 +12656,7 @@ int main (int argc, char **argv) test_write_bond_main (); test_write_bond_slave (); test_write_bond_slave_ib (); + g_test_add_func (TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric); /* bridging */ test_read_bridge_main (); diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c index 5b9e9d79..4b7cb43d 100644 --- a/src/settings/plugins/ifcfg-rh/utils.c +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -356,6 +356,30 @@ gone: } gboolean +utils_has_complex_routes (const char *filename) +{ + char *rules; + + g_return_val_if_fail (filename != NULL, TRUE); + + rules = utils_get_extra_path (filename, RULE_TAG); + if (g_file_test (rules, G_FILE_TEST_EXISTS)) { + g_free (rules); + return TRUE; + } + g_free (rules); + + rules = utils_get_extra_path (filename, RULE6_TAG); + if (g_file_test (rules, G_FILE_TEST_EXISTS)) { + g_free (rules); + return TRUE; + } + g_free (rules); + + return FALSE; +} + +gboolean utils_ignore_ip_config (NMConnection *connection) { NMSettingConnection *s_con; diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h index 95af828b..445437c4 100644 --- a/src/settings/plugins/ifcfg-rh/utils.h +++ b/src/settings/plugins/ifcfg-rh/utils.h @@ -25,6 +25,13 @@ #include <nm-connection.h> #include "shvar.h" #include "common.h" +#include "nm-logging.h" + +#define NM_IFCFG_CONNECTION_LOG_PATH(path) str_if_set (path,"in-memory") +#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")" +#define NM_IFCFG_CONNECTION_LOG_ARG(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)) +#define NM_IFCFG_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" +#define NM_IFCFG_CONNECTION_LOG_ARGD(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)), (con) char *utils_single_quote_string (const char *str); @@ -47,6 +54,7 @@ shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create); shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create); gboolean utils_has_route_file_new_syntax (const char *filename); +gboolean utils_has_complex_routes (const char *filename); gboolean utils_ignore_ip_config (NMConnection *connection); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index f4ffffd6..d2b0c970 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -44,6 +44,7 @@ #include <nm-utils.h> #include "nm-logging.h" +#include "gsystem-local-alloc.h" #include "common.h" #include "shvar.h" #include "reader.h" @@ -695,9 +696,15 @@ write_wireless_security_setting (NMConnection *connection, * keys. */ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + if (key_type == NM_WEP_KEY_TYPE_UNKNOWN) { + if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_KEY)) + key_type = NM_WEP_KEY_TYPE_KEY; + else if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_PASSPHRASE)) + key_type = NM_WEP_KEY_TYPE_PASSPHRASE; + } if (key_type == NM_WEP_KEY_TYPE_PASSPHRASE) tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); - else { + else if (key_type == NM_WEP_KEY_TYPE_KEY) { tmp = g_strdup_printf ("KEY%d", i + 1); /* Add 's:' prefix for ASCII keys */ @@ -705,7 +712,8 @@ write_wireless_security_setting (NMConnection *connection, ascii_key = g_strdup_printf ("s:%s", key); key = ascii_key; } - } + } else + key = NULL; set_secret (ifcfg, tmp, @@ -1806,6 +1814,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) char *route_path = NULL; gint32 j; guint32 i, n, num; + gint64 route_metric; GString *searches; gboolean success = FALSE; gboolean fake_ip4 = FALSE; @@ -2015,6 +2024,11 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) nm_setting_ip_config_get_may_fail (s_ip4) ? "no" : "yes", FALSE); + route_metric = nm_setting_ip_config_get_route_metric (s_ip4); + tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL; + svSetValue (ifcfg, "IPV4_ROUTE_METRIC", tmp, FALSE); + g_free (tmp); + /* Static routes - route-<name> file */ route_path = utils_get_route_path (ifcfg->fileName); if (!route_path) { @@ -2105,13 +2119,16 @@ static void write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) { NMSettingIPConfig *s_ip4; - char *base_ifcfg_dir, *base_ifcfg_name, *base_name; + gs_free char *base_ifcfg_dir = NULL, *base_ifcfg_name = NULL; + const char*base_name; int i, num, base_ifcfg_name_len, base_name_len; GDir *dir; base_ifcfg_dir = g_path_get_dirname (base_ifcfg_path); base_ifcfg_name = g_path_get_basename (base_ifcfg_path); base_ifcfg_name_len = strlen (base_ifcfg_name); + if (!g_str_has_prefix (base_ifcfg_name, IFCFG_TAG)) + g_return_if_reached (); base_name = base_ifcfg_name + strlen (IFCFG_TAG); base_name_len = strlen (base_name); @@ -2183,9 +2200,6 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) svWriteFile (ifcfg, 0644, NULL); svCloseFile (ifcfg); } - - g_free (base_ifcfg_name); - g_free (base_ifcfg_dir); } static gboolean @@ -2249,10 +2263,12 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) NMSettingIPConfig *s_ip4; const char *value; char *addr_key; + char *tmp; guint32 i, num, num4; GString *searches; NMIPAddress *addr; const char *dns; + gint64 route_metric; GString *ip_str1, *ip_str2, *ip_ptr; char *route6_path; @@ -2266,6 +2282,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "IPV6_PEERDNS", "yes", FALSE); svSetValue (ifcfg, "IPV6_PEERROUTES", "yes", FALSE); svSetValue (ifcfg, "IPV6_FAILURE_FATAL", "no", FALSE); + svSetValue (ifcfg, "IPV6_ROUTE_METRIC", NULL, FALSE); return TRUE; } @@ -2380,6 +2397,11 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) nm_setting_ip_config_get_may_fail (s_ip6) ? "no" : "yes", FALSE); + route_metric = nm_setting_ip_config_get_route_metric (s_ip6); + tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL; + svSetValue (ifcfg, "IPV6_ROUTE_METRIC", tmp, FALSE); + g_free (tmp); + /* IPv6 Privacy Extensions */ svSetValue (ifcfg, "IPV6_PRIVACY", NULL, FALSE); svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", NULL, FALSE); @@ -2624,6 +2646,12 @@ writer_update_connection (NMConnection *connection, const char *keyfile, GError **error) { + if (utils_has_complex_routes (filename)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file"); + return FALSE; + } + return write_connection (connection, ifcfg_dir, filename, keyfile, NULL, error); } diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in index 149faa3e..f7df30b4 100644 --- a/src/settings/plugins/ifcfg-suse/Makefile.in +++ b/src/settings/plugins/ifcfg-suse/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifcfg-suse -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -203,6 +212,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -229,7 +240,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -264,6 +274,7 @@ 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@ @@ -498,7 +509,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -568,14 +578,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -797,6 +807,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + # 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/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in index 11e9297f..cbedcd79 100644 --- a/src/settings/plugins/ifnet/Makefile.in +++ b/src/settings/plugins/ifnet/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifnet -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -226,6 +235,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -277,7 +288,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -312,6 +322,7 @@ 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@ @@ -562,7 +573,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -651,14 +661,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -954,6 +964,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ -DSBINDIR=\"$(sbindir)\" diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index 1cf46fbf..755767e2 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -396,7 +396,11 @@ ifnet_init (gchar * config_file) const char * ifnet_get_data (const char *conn_name, const char *key) { - GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); + GHashTable *conn; + + g_return_val_if_fail (conn_name && key, NULL); + + conn = g_hash_table_lookup (conn_table, conn_name); if (conn) return g_hash_table_lookup (conn, key); diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.c b/src/settings/plugins/ifnet/nm-ifnet-connection.c index c84ad5ed..693e6532 100644 --- a/src/settings/plugins/ifnet/nm-ifnet-connection.c +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.c @@ -82,6 +82,7 @@ nm_ifnet_connection_new (NMConnection *source, const char *conn_name) nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, update_unsaved, + NULL, NULL); g_object_unref (tmp); diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index 3eb1ed52..33711639 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -313,10 +313,13 @@ reload_connections (NMSystemConfigInterface *config) if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (old), NM_CONNECTION (new), FALSE, /* don't set Unsaved */ + "ifnet-update", &error)) { - /* Shouldn't ever get here as 'new' was verified by the reader already */ - g_assert_no_error (error); + /* Shouldn't ever get here as 'new' was verified by the reader already + * and the UUID did not change. */ + g_assert_not_reached (); } + g_assert_no_error (error); nm_log_info (LOGD_SETTINGS, "Connection %s updated", nm_connection_get_id (NM_CONNECTION (new))); } @@ -393,7 +396,7 @@ check_unmanaged (gpointer key, gpointer data, gpointer user_data) conn_name = nm_ifnet_connection_get_conn_name (connection); - if (is_managed (conn_name)) + if (!conn_name || is_managed (conn_name)) return; nm_log_info (LOGD_SETTINGS, "Checking unmanaged: %s", conn_name); diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in index 8293c869..5b0dcc8d 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.in +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -80,8 +90,6 @@ build_triplet = @build@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = check_ifnet$(EXEEXT) subdir = src/settings/plugins/ifnet/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -98,6 +106,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -179,6 +188,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -205,7 +216,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -240,6 +250,7 @@ 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@ @@ -492,7 +503,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -541,14 +551,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -824,6 +834,8 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index 9c399128..76ed0c7d 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -448,8 +448,7 @@ main (int argc, char **argv) nm_linux_platform_setup (); - nmtst_init_assert_logging (&argc, &argv); - nm_logging_setup ("WARN", "DEFAULT", NULL, NULL); + nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); f = g_build_filename (argv[1], "net", NULL); ifnet_init (f); diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in index 44596e48..6d0da08c 100644 --- a/src/settings/plugins/ifupdown/Makefile.in +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/ifupdown -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -225,6 +234,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -276,7 +287,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -311,6 +321,7 @@ 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@ @@ -557,7 +568,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -644,14 +654,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -947,6 +957,8 @@ uninstall-am: uninstall-pkglibLTLIBRARIES mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am index 24cdd955..2e927db9 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.am +++ b/src/settings/plugins/ifupdown/tests/Makefile.am @@ -23,6 +23,8 @@ test_ifupdown_SOURCES = \ test_ifupdown_LDADD = \ $(top_builddir)/src/libNetworkManager.la +# TODO: enable valgrind for ifupdown. Currently it fails. +#@VALGRIND_RULES@ TESTS = test-ifupdown endif diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in index 6dedec00..d8c5b39e 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.in +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-ifupdown$(EXEEXT) @ENABLE_TESTS_TRUE@TESTS = test-ifupdown$(EXEEXT) subdir = src/settings/plugins/ifupdown/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -197,6 +206,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -223,7 +234,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -258,6 +268,7 @@ 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@ @@ -501,7 +512,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -548,14 +558,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -895,6 +905,8 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + # 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/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index 8c0d11af..21c5577c 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,8 +89,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/keyfile -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -97,6 +105,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -194,6 +203,8 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -245,7 +256,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -280,6 +290,7 @@ 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@ @@ -538,7 +549,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -591,14 +601,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -892,6 +902,8 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + @GNOME_CODE_COVERAGE_RULES@ diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h index db6569e5..7bde4bf3 100644 --- a/src/settings/plugins/keyfile/common.h +++ b/src/settings/plugins/keyfile/common.h @@ -24,7 +24,7 @@ #include <glib.h> #define KEYFILE_PLUGIN_NAME "keyfile" -#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2013 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." +#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2015 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." #define KEYFILE_DIR NMCONFDIR "/system-connections" diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c index c852f028..8fb94302 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.c +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c @@ -36,19 +36,12 @@ G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION) -#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) - -typedef struct { - char *path; -} NMKeyfileConnectionPrivate; - NMKeyfileConnection * nm_keyfile_connection_new (NMConnection *source, const char *full_path, GError **error) { GObject *object; - NMKeyfileConnectionPrivate *priv; NMConnection *tmp; const char *uuid; gboolean update_unsaved = TRUE; @@ -75,15 +68,15 @@ nm_keyfile_connection_new (NMConnection *source, update_unsaved = FALSE; } - object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); - - priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - priv->path = g_strdup (full_path); + object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, + NM_SETTINGS_CONNECTION_FILENAME, full_path, + NULL); /* Update our settings with what was read from the file */ if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, update_unsaved, + NULL, error)) { g_object_unref (object); object = NULL; @@ -93,38 +86,16 @@ nm_keyfile_connection_new (NMConnection *source, return (NMKeyfileConnection *) object; } -const char * -nm_keyfile_connection_get_path (NMKeyfileConnection *self) -{ - g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL); - - return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path; -} - -void -nm_keyfile_connection_set_path (NMKeyfileConnection *self, const char *path) -{ - NMKeyfileConnectionPrivate *priv; - - g_return_if_fail (NM_IS_KEYFILE_CONNECTION (self)); - g_return_if_fail (path != NULL); - - priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (self); - g_free (priv->path); - priv->path = g_strdup (path); -} - static void commit_changes (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data) { - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); char *path = NULL; GError *error = NULL; if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), - priv->path, + nm_settings_connection_get_filename (connection), &path, &error)) { callback (connection, error, user_data); @@ -133,10 +104,8 @@ commit_changes (NMSettingsConnection *connection, } /* Update the filename if it changed */ - if (path) { - g_free (priv->path); - priv->path = path; - } + if (path) + nm_settings_connection_set_filename (connection, path); NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, callback, @@ -148,10 +117,11 @@ do_delete (NMSettingsConnection *connection, NMSettingsConnectionDeleteFunc callback, gpointer user_data) { - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); + const char *path; - if (priv->path) - g_unlink (priv->path); + path = nm_settings_connection_get_filename (connection); + if (path) + g_unlink (path); NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, callback, @@ -166,23 +136,11 @@ nm_keyfile_connection_init (NMKeyfileConnection *connection) } static void -finalize (GObject *object) -{ - g_free (NM_KEYFILE_CONNECTION_GET_PRIVATE (object)->path); - - G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object); -} - -static void nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) { - GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class); NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class); - g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); - /* Virtual methods */ - object_class->finalize = finalize; settings_class->commit_changes = commit_changes; settings_class->delete = do_delete; } diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h index 135bb49f..f6fa432b 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.h +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -47,9 +47,6 @@ NMKeyfileConnection *nm_keyfile_connection_new (NMConnection *source, const char *filename, GError **error); -const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self); -void nm_keyfile_connection_set_path (NMKeyfileConnection *self, const char *path); - G_END_DECLS #endif /* __NETWORKMANAGER_KEYFILE_CONNECTION_H__ */ diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index 371fa47a..fcdb3c3c 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -45,6 +45,7 @@ #include "writer.h" #include "common.h" #include "utils.h" +#include "gsystem-local-alloc.h" static char *plugin_get_hostname (SCPluginKeyfile *plugin); static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); @@ -87,7 +88,7 @@ remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection) g_return_if_fail (connection != NULL); - nm_log_info (LOGD_SETTINGS, "removed %s.", nm_keyfile_connection_get_path (connection)); + nm_log_info (LOGD_SETTINGS, "keyfile: removed " NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection)); /* Removing from the hash table should drop the last reference */ g_object_ref (connection); @@ -100,102 +101,182 @@ remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection) g_return_if_fail (removed); } -static void -update_connection (SCPluginKeyfile *self, - NMKeyfileConnection *connection, - const char *name) -{ - NMKeyfileConnection *tmp; - GError *error = NULL; - - tmp = nm_keyfile_connection_new (NULL, name, &error); - if (!tmp) { - /* Error; remove the connection */ - nm_log_warn (LOGD_SETTINGS, " error in connection %s: %s", name, - (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - remove_connection (self, connection); - return; - } - - if (!nm_connection_compare (NM_CONNECTION (connection), - NM_CONNECTION (tmp), - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { - nm_log_info (LOGD_SETTINGS, "updating %s", name); - if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection), - NM_CONNECTION (tmp), - FALSE, /* don't set Unsaved */ - &error)) { - /* Shouldn't ever get here as 'new' was verified by the reader already */ - g_assert_no_error (error); - } - } - g_object_unref (tmp); -} - static NMKeyfileConnection * find_by_path (SCPluginKeyfile *self, const char *path) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); GHashTableIter iter; - NMKeyfileConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; g_return_val_if_fail (path != NULL, NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (path, nm_keyfile_connection_get_path (candidate)) == 0) - return candidate; + if (g_strcmp0 (path, nm_settings_connection_get_filename (candidate)) == 0) + return NM_KEYFILE_CONNECTION (candidate); } return NULL; } -static void -new_connection (SCPluginKeyfile *self, - const char *name, - char **out_old_path) +/* update_connection: + * @self: the plugin instance + * @source: if %NULL, this re-reads the connection from @full_path + * and updates it. When passing @source, this adds a connection from + * memory. + * @full_path: the filename of the keyfile to be loaded + * @connection: an existing connection that might be updated. + * If given, @connection must be an existing connection that is currently + * owned by the plugin. + * @protect_existing_connection: if %TRUE, and !@connection, we don't allow updating + * an existing connection with the same UUID. + * If %TRUE and @connection, allow updating only if the reload would modify + * @connection (without changing its UUID) or if we would create a new connection. + * In other words, if this paramter is %TRUE, we only allow creating a + * new connection (with an unseen UUID) or updating the passed in @connection + * (whereas the UUID cannot change). + * Note, that this allows for @connection to be replaced by a new connection. + * @protected_connections: (allow-none): if given, we only update an + * existing connection if it is not contained in this hash. + * @error: error in case of failure + * + * Loads a connection from file @full_path. This can both be used to + * load a connection initially or to update an existing connection. + * + * If you pass in an existing connection and the reloaded file happens + * to have a different UUID, the connection is deleted. + * Beware, that means that after the function, you have a dangling pointer + * if the returned connection is different from @connection. + * + * Returns: the updated connection. + * */ +static NMKeyfileConnection * +update_connection (SCPluginKeyfile *self, + NMConnection *source, + const char *full_path, + NMKeyfileConnection *connection, + gboolean protect_existing_connection, + GHashTable *protected_connections, + GError **error) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - NMKeyfileConnection *tmp, *connection; - GError *error = NULL; + NMKeyfileConnection *connection_new; + NMKeyfileConnection *connection_by_uuid; + GError *local = NULL; const char *uuid; - if (out_old_path) - *out_old_path = NULL; + g_return_val_if_fail (!source || NM_IS_CONNECTION (source), NULL); + g_return_val_if_fail (full_path || source, NULL); - tmp = nm_keyfile_connection_new (NULL, name, &error); - if (!tmp) { - nm_log_warn (LOGD_SETTINGS, " error in connection %s: %s", name, - (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - return; + if (full_path) + nm_log_dbg (LOGD_SETTINGS, "keyfile: loading from file \"%s\"...", full_path); + + connection_new = nm_keyfile_connection_new (source, full_path, &local); + if (!connection_new) { + /* Error; remove the connection */ + if (source) + nm_log_warn (LOGD_SETTINGS, "keyfile: error creating connection %s: %s", nm_connection_get_uuid (source), local->message); + else + nm_log_warn (LOGD_SETTINGS, "keyfile: error loading connection from file %s: %s", full_path, local->message); + if ( connection + && !protect_existing_connection + && (!protected_connections || !g_hash_table_contains (protected_connections, connection))) + remove_connection (self, connection); + g_propagate_error (error, local); + return NULL; + } + + uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new)); + connection_by_uuid = g_hash_table_lookup (priv->connections, uuid); + + if ( connection + && connection != connection_by_uuid) { + + if ( (protect_existing_connection && connection_by_uuid != NULL) + || (protected_connections && g_hash_table_contains (protected_connections, connection))) { + NMKeyfileConnection *conflicting = (protect_existing_connection && connection_by_uuid != NULL) ? connection_by_uuid : connection; + + if (source) + nm_log_warn (LOGD_SETTINGS, "keyfile: cannot update protected "NM_KEYFILE_CONNECTION_LOG_FMT" connection due to conflicting UUID %s", NM_KEYFILE_CONNECTION_LOG_ARG (conflicting), uuid); + else + nm_log_warn (LOGD_SETTINGS, "keyfile: cannot load %s due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, full_path, NM_KEYFILE_CONNECTION_LOG_ARG (conflicting)); + g_object_unref (connection_new); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot update protected connection due to conflicting UUID"); + return NULL; + } + + /* The new connection has a different UUID then the original one. + * Remove @connection. */ + remove_connection (self, connection); } - /* Connection renames will show as different paths but same UUID */ - uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); - connection = g_hash_table_lookup (priv->connections, uuid); - if (connection) { - nm_log_info (LOGD_SETTINGS, "rename %s -> %s", nm_keyfile_connection_get_path (connection), name); - if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection), - NM_CONNECTION (tmp), - FALSE, /* don't set Unsaved */ - &error)) { - /* Shouldn't ever get here as 'tmp' was verified by the reader already */ - g_assert_no_error (error); + if ( connection_by_uuid + && ( (!connection && protect_existing_connection) + || (protected_connections && g_hash_table_contains (protected_connections, connection_by_uuid)))) { + if (source) + nm_log_warn (LOGD_SETTINGS, "keyfile: cannot update connection due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_by_uuid)); + else + nm_log_warn (LOGD_SETTINGS, "keyfile: cannot load %s due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, full_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_by_uuid)); + g_object_unref (connection_new); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Skip updating protected connection during reload"); + return NULL; + } + + if (connection_by_uuid) { + const char *old_path; + + old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)); + + if (nm_connection_compare (NM_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { + /* Nothing to do... except updating the path. */ + if (old_path && g_strcmp0 (old_path, full_path) != 0) + nm_log_info (LOGD_SETTINGS, "keyfile: rename \"%s\" to "NM_KEYFILE_CONNECTION_LOG_FMT" without other changes", old_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + } else { + /* An existing connection changed. */ + if (source) + nm_log_info (LOGD_SETTINGS, "keyfile: update "NM_KEYFILE_CONNECTION_LOG_FMT" from %s", NM_KEYFILE_CONNECTION_LOG_ARG (connection_new), NM_KEYFILE_CONNECTION_LOG_PATH (old_path)); + else if (!g_strcmp0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new)))) + nm_log_info (LOGD_SETTINGS, "keyfile: update "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + else if (old_path) + nm_log_info (LOGD_SETTINGS, "keyfile: rename \"%s\" to "NM_KEYFILE_CONNECTION_LOG_FMT, old_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + else + nm_log_info (LOGD_SETTINGS, "keyfile: update and persist "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), + FALSE, /* don't set Unsaved */ + "keyfile-update", + &local)) { + /* Shouldn't ever get here as 'connection_new' was verified by the reader already + * and the UUID did not change. */ + g_assert_not_reached (); + } + g_assert_no_error (local); } - g_object_unref (tmp); - if (out_old_path) - *out_old_path = g_strdup (nm_keyfile_connection_get_path (connection)); - nm_keyfile_connection_set_path (connection, name); + nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (connection_by_uuid), full_path); + g_object_unref (connection_new); + return connection_by_uuid; } else { - nm_log_info (LOGD_SETTINGS, "new connection %s", name); - g_hash_table_insert (priv->connections, g_strdup (uuid), tmp); - g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, tmp); + if (source) + nm_log_info (LOGD_SETTINGS, "keyfile: add connection "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + else + nm_log_info (LOGD_SETTINGS, "keyfile: new connection "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new)); + g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new); - g_signal_connect (tmp, NM_SETTINGS_CONNECTION_REMOVED, + g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), self); + + if (!source) { + /* Only raise the signal if we were called without source, i.e. if we read the connection from file. + * Otherwise, we were called by add_connection() which does not expect the signal. */ + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_new); + } + return connection_new; } } @@ -210,26 +291,28 @@ dir_changed (GFileMonitor *monitor, SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); NMKeyfileConnection *connection; char *full_path; + gboolean exists; full_path = g_file_get_path (file); if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) { g_free (full_path); return; } + exists = g_file_test (full_path, G_FILE_TEST_EXISTS); + + nm_log_dbg (LOGD_SETTINGS, "dir_changed(%s) = %d; file %s", full_path, event_type, exists ? "exists" : "does not exist"); connection = find_by_path (self, full_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: - if (connection) + if (!exists && connection) remove_connection (SC_PLUGIN_KEYFILE (config), connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - if (connection) - update_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); - else - new_connection (SC_PLUGIN_KEYFILE (config), full_path, NULL); + if (exists) + update_connection (SC_PLUGIN_KEYFILE (config), NULL, full_path, connection, TRUE, NULL, NULL); break; default: break; @@ -305,6 +388,43 @@ setup_monitoring (NMSystemConfigInterface *config) } } +static GHashTable * +_paths_from_connections (GHashTable *connections) +{ + GHashTableIter iter; + NMKeyfileConnection *connection; + GHashTable *paths = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_iter_init (&iter, connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + const char *path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); + + if (path) + g_hash_table_add (paths, (void *) path); + } + return paths; +} + +static int +_sort_paths (const char **f1, const char **f2, GHashTable *paths) +{ + struct stat st; + gboolean c1, c2; + gint64 m1, m2; + + c1 = !!g_hash_table_contains (paths, *f1); + c2 = !!g_hash_table_contains (paths, *f2); + if (c1 != c2) + return c1 ? -1 : 1; + + m1 = stat (*f1, &st) == 0 ? (gint64) st.st_mtime : G_MININT64; + m2 = stat (*f2, &st) == 0 ? (gint64) st.st_mtime : G_MININT64; + if (m1 != m2) + return m1 > m2 ? -1 : 1; + + return strcmp (*f1, *f2); +} + static void read_connections (NMSystemConfigInterface *config) { @@ -313,13 +433,17 @@ read_connections (NMSystemConfigInterface *config) GDir *dir; GError *error = NULL; const char *item; - GHashTable *oldconns; + GHashTable *alive_connections; GHashTableIter iter; - gpointer data; + NMKeyfileConnection *connection; + GPtrArray *dead_connections = NULL; + guint i; + GPtrArray *filenames; + GHashTable *paths; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { - nm_log_warn (LOGD_SETTINGS, "Cannot read directory '%s': (%d) %s", + nm_log_warn (LOGD_SETTINGS, "keyfile: cannot read directory '%s': (%d) %s", KEYFILE_DIR, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -327,45 +451,49 @@ read_connections (NMSystemConfigInterface *config) return; } - oldconns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - const char *con_path = nm_keyfile_connection_get_path (data); - if (con_path) - g_hash_table_insert (oldconns, g_strdup (con_path), data); - } + alive_connections = g_hash_table_new (NULL, NULL); + filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { - NMKeyfileConnection *connection; - char *full_path, *old_path; - if (nm_keyfile_plugin_utils_should_ignore_file (item)) continue; + g_ptr_array_add (filenames, g_build_filename (KEYFILE_DIR, item, NULL)); + } + g_dir_close (dir); - full_path = g_build_filename (KEYFILE_DIR, item, NULL); + /* While reloading, we don't replace connections that we already loaded while + * iterating over the files. + * + * To have sensible, reproducible behavior, sort the paths by last modification + * time prefering older files. + */ + paths = _paths_from_connections (priv->connections); + g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths); + g_hash_table_destroy (paths); + + for (i = 0; i < filenames->len; i++) { + connection = update_connection (self, NULL, filenames->pdata[i], NULL, FALSE, alive_connections, NULL); + if (connection) + g_hash_table_add (alive_connections, connection); + } + g_ptr_array_free (filenames, TRUE); - connection = g_hash_table_lookup (oldconns, full_path); - if (connection) { - g_hash_table_remove (oldconns, full_path); - update_connection (self, connection, full_path); - } else { - new_connection (self, full_path, &old_path); - if (old_path) { - g_hash_table_remove (oldconns, old_path); - g_free (old_path); - } + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) { + if ( !g_hash_table_contains (alive_connections, connection) + && nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))) { + if (!dead_connections) + dead_connections = g_ptr_array_new (); + g_ptr_array_add (dead_connections, connection); } - - g_free (full_path); } - g_dir_close (dir); + g_hash_table_destroy (alive_connections); - g_hash_table_iter_init (&iter, oldconns); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - g_hash_table_iter_remove (&iter); - remove_connection (self, data); + if (dead_connections) { + for (i = 0; i < dead_connections->len; i++) + remove_connection (self, dead_connections->pdata[i]); + g_ptr_array_free (dead_connections, TRUE); } - g_hash_table_destroy (oldconns); } /* Plugin */ @@ -399,13 +527,7 @@ load_connection (NMSystemConfigInterface *config, if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1)) return FALSE; - connection = find_by_path (self, filename); - if (connection) - update_connection (self, connection, filename); - else { - new_connection (self, filename, NULL); - connection = find_by_path (self, filename); - } + connection = update_connection (self, NULL, filename, find_by_path (self, filename), TRUE, NULL, NULL); return (connection != NULL); } @@ -423,26 +545,13 @@ add_connection (NMSystemConfigInterface *config, GError **error) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - NMSettingsConnection *added = NULL; - char *path = NULL; + gs_free char *path = NULL; if (save_to_disk) { if (!nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) return NULL; } - - added = (NMSettingsConnection *) nm_keyfile_connection_new (connection, path, error); - if (added) { - g_hash_table_insert (priv->connections, - g_strdup (nm_connection_get_uuid (NM_CONNECTION (added))), - added); - g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (connection_removed_cb), - self); - } - g_free (path); - return added; + return NM_SETTINGS_CONNECTION (update_connection (self, connection, path, NULL, FALSE, NULL, error)); } static gboolean @@ -500,7 +609,7 @@ get_unmanaged_specs (NMSystemConfigInterface *config) } else if (!strncmp (udis[i], "interface-name:", 15) && nm_utils_iface_valid_name (udis[i] + 15)) { specs = g_slist_append (specs, udis[i]); } else { - nm_log_warn (LOGD_SETTINGS, "Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); + nm_log_warn (LOGD_SETTINGS, "keyfile: error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); g_free (udis[i]); } } @@ -510,7 +619,7 @@ get_unmanaged_specs (NMSystemConfigInterface *config) out: if (error) { - nm_log_warn (LOGD_SETTINGS, "%s", error->message); + nm_log_warn (LOGD_SETTINGS, "keyfile: error getting unmanaged specs: %s", error->message); g_error_free (error); } if (key_file) @@ -538,7 +647,7 @@ plugin_get_hostname (SCPluginKeyfile *plugin) out: if (error) { - nm_log_warn (LOGD_SETTINGS, "%s", error->message); + nm_log_warn (LOGD_SETTINGS, "keyfile: error getting hostname: %s", error->message); g_error_free (error); } if (key_file) @@ -585,7 +694,7 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) out: if (error) { - nm_log_warn (LOGD_SETTINGS, "%s", error->message); + nm_log_warn (LOGD_SETTINGS, "keyfile: error setting hostname: %s", error->message); g_error_free (error); } g_free (data); diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 1d2ecdad..1f0953e0 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -870,6 +870,7 @@ parity_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const cha int_val = 'X'; } } + g_free (str_val); } if (!int_val) diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am index 20b9820c..a79e20b5 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.am +++ b/src/settings/plugins/keyfile/tests/Makefile.am @@ -34,6 +34,7 @@ test_keyfile_LDADD = \ $(DBUS_LIBS) \ $(CODE_COVERAGE_LDFLAGS) +@VALGRIND_RULES@ TESTS = test-keyfile endif diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index 8530bf8c..c4d12459 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-keyfile$(EXEEXT) @ENABLE_TESTS_TRUE@TESTS = test-keyfile$(EXEEXT) subdir = src/settings/plugins/keyfile/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -217,6 +226,8 @@ am__tty_colors = { \ fi; \ } DIST_SUBDIRS = keyfiles +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -268,7 +279,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -303,6 +313,7 @@ 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@ @@ -548,7 +559,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -596,14 +606,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1031,9 +1041,13 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am +.PRECIOUS: Makefile + @ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ +@ENABLE_TESTS_TRUE@@VALGRIND_RULES@ + # 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. .NOEXPORT: diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index bc522b1b..f7a0c45e 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,7 +88,6 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/settings/plugins/keyfile/tests/keyfiles -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -95,6 +104,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -119,6 +129,7 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -145,7 +156,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -180,6 +190,7 @@ 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@ @@ -434,7 +445,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -611,6 +621,8 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am +.PRECIOUS: Makefile + check-local: @for f in $(KEYFILES); do \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main b/src/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main index 7fbbfe22..3b9fcb28 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main @@ -6,7 +6,7 @@ type=bridge [bridge] interface-name=br0 stp=true -forward-delay=0 +forward-delay=2 priority=32744 hello-time=7 max-age=39 diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index 33e3863c..edece1b2 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -1515,6 +1515,7 @@ test_write_intlike_ssid (void) g_assert_no_error (error); g_assert (tmp); g_assert_cmpstr (tmp, ==, "101"); + g_free (tmp); g_key_file_free (keyfile); @@ -1601,6 +1602,7 @@ test_write_intlike_ssid_2 (void) g_assert_no_error (error); g_assert (tmp); g_assert_cmpstr (tmp, ==, "11\\;12\\;13\\;"); + g_free (tmp); g_key_file_free (keyfile); @@ -2511,6 +2513,7 @@ test_write_wired_8021x_tls_connection_path (void) tmp2 = g_path_get_dirname (testfile); if (g_strcmp0 (tmp2, TEST_KEYFILES_DIR) == 0) relative = TRUE; + g_free (tmp2); /* CA cert */ tmp = g_key_file_get_string (keyfile, @@ -2564,10 +2567,22 @@ test_write_wired_8021x_tls_connection_blob (void) char *new_priv_key; const char *uuid; GError *error = NULL; + GBytes *password_raw = NULL; +#define PASSWORD_RAW "password-raw\0test" connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_BLOB); g_assert (connection != NULL); + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + password_raw = g_bytes_new (PASSWORD_RAW, STRLEN (PASSWORD_RAW)); + g_object_set (s_8021x, + NM_SETTING_802_1X_PASSWORD_RAW, + password_raw, + NULL); + g_bytes_unref (password_raw); + /* Write out the connection */ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, geteuid (), getegid (), &testfile, &error); if (!success) { @@ -2610,6 +2625,11 @@ test_write_wired_8021x_tls_connection_blob (void) g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); g_assert (nm_setting_802_1x_get_private_key_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + password_raw = nm_setting_802_1x_get_password_raw (s_8021x); + g_assert (password_raw); + g_assert (g_bytes_get_size (password_raw) == STRLEN (PASSWORD_RAW)); + g_assert (!memcmp (g_bytes_get_data (password_raw, NULL), PASSWORD_RAW, STRLEN (PASSWORD_RAW))); + unlink (testfile); g_free (testfile); @@ -2784,7 +2804,7 @@ test_read_bridge_main (void) /* Bridge setting */ s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); - g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 0); + g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 2); g_assert_cmpuint (nm_setting_bridge_get_stp (s_bridge), ==, TRUE); g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7); @@ -3098,6 +3118,7 @@ test_write_new_wired_group_name (void) unlink (testfile); g_free (testfile); + g_key_file_unref (kf); g_object_unref (reread); g_object_unref (connection); } @@ -3236,6 +3257,7 @@ test_write_new_wireless_group_names (void) unlink (testfile); g_free (testfile); + g_key_file_unref (kf); g_object_unref (reread); g_object_unref (connection); } @@ -3548,7 +3570,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); /* The tests */ g_test_add_func ("/keyfile/test_read_valid_wired_connection ", test_read_valid_wired_connection); diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h index 1a7c2502..d1533671 100644 --- a/src/settings/plugins/keyfile/utils.h +++ b/src/settings/plugins/keyfile/utils.h @@ -23,6 +23,13 @@ #include <glib.h> #include "common.h" +#include "NetworkManagerUtils.h" + +#define NM_KEYFILE_CONNECTION_LOG_PATH(path) str_if_set (path,"in-memory") +#define NM_KEYFILE_CONNECTION_LOG_FMT "%s (%s,\"%s\")" +#define NM_KEYFILE_CONNECTION_LOG_ARG(con) NM_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)) +#define NM_KEYFILE_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" +#define NM_KEYFILE_CONNECTION_LOG_ARGD(con) NM_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)), (con) gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename); diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index d342e3f7..7aa5bfb0 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -27,7 +27,6 @@ #include <stdio.h> #include <errno.h> -#include <dbus/dbus-glib.h> #include <nm-setting.h> #include <nm-setting-connection.h> #include <nm-setting-ip4-config.h> @@ -42,7 +41,6 @@ #include <string.h> #include <arpa/inet.h> -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-logging.h" #include "writer.h" @@ -345,19 +343,24 @@ password_raw_writer (GKeyFile *file, const GValue *value) { const char *setting_name = nm_setting_get_name (setting); - GByteArray *array; - int i, *tmp_array; + GBytes *array; + int *tmp_array; + gsize i, len; + const char *data; - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); + g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES)); - array = (GByteArray *) g_value_get_boxed (value); - if (!array || !array->len) + array = (GBytes *) g_value_get_boxed (value); + if (!array) + return; + data = g_bytes_get_data (array, &len); + if (!data || !len) return; - tmp_array = g_new (gint, array->len); - for (i = 0; i < array->len; i++) - tmp_array[i] = (int) array->data[i]; - nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, array->len); + tmp_array = g_new (gint, len); + for (i = 0; i < len; i++) + tmp_array[i] = (int) data[i]; + nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, len); g_free (tmp_array); } @@ -813,13 +816,10 @@ _internal_write_connection (NMConnection *connection, WriteInfo info; GError *local_err = NULL; - if (out_path) - g_return_val_if_fail (*out_path == NULL, FALSE); + g_return_val_if_fail (!out_path || !*out_path, FALSE); - if (!nm_connection_verify (connection, error)) { + if (!nm_connection_verify (connection, error)) g_return_val_if_reached (FALSE); - return FALSE; - } id = nm_connection_get_id (connection); g_assert (id && *id); diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c index 9ae87095..c60027ad 100644 --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -547,6 +547,13 @@ add_wep_key (NMSupplicantConfig *self, if (!key || !key_len) return TRUE; + if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) { + if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_KEY)) + wep_type = NM_WEP_KEY_TYPE_KEY; + else if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_PASSPHRASE)) + wep_type = NM_WEP_KEY_TYPE_PASSPHRASE; + } + if ( (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) || (wep_type == NM_WEP_KEY_TYPE_KEY)) { if ((key_len == 10) || (key_len == 26)) { diff --git a/src/supplicant-manager/tests/Makefile.am b/src/supplicant-manager/tests/Makefile.am index 452ccdc1..85268dcf 100644 --- a/src/supplicant-manager/tests/Makefile.am +++ b/src/supplicant-manager/tests/Makefile.am @@ -18,4 +18,5 @@ test_supplicant_config_SOURCES = \ test_supplicant_config_LDADD = \ $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-supplicant-config diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in index 567b6c77..50981a19 100644 --- a/src/supplicant-manager/tests/Makefile.in +++ b/src/supplicant-manager/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ noinst_PROGRAMS = test-supplicant-config$(EXEEXT) TESTS = test-supplicant-config$(EXEEXT) subdir = src/supplicant-manager/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -194,6 +203,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -220,7 +231,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -255,6 +265,7 @@ 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@ @@ -489,7 +500,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/supplicant-manager/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/supplicant-manager/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -534,14 +544,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -853,6 +863,10 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +@VALGRIND_RULES@ # 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/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c index 5aa3fa2d..5ffead40 100644 --- a/src/supplicant-manager/tests/test-supplicant-config.c +++ b/src/supplicant-manager/tests/test-supplicant-config.c @@ -111,7 +111,7 @@ test_wifi_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingIPConfig *s_ip4; - NMSupplicantConfig *config; + gs_unref_object NMSupplicantConfig *config = NULL; GHashTable *hash; char *uuid; gboolean success; @@ -191,6 +191,7 @@ test_wifi_open (void) validate_opt ("wifi-open", hash, "bssid", TYPE_KEYWORD, bssid_str, -1); validate_opt ("wifi-open", hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1); + g_hash_table_unref (hash); g_object_unref (connection); } @@ -206,7 +207,7 @@ test_wifi_wep_key (const char *detail, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - NMSupplicantConfig *config; + gs_unref_object NMSupplicantConfig *config = NULL; GHashTable *hash; char *uuid; gboolean success; @@ -305,6 +306,7 @@ test_wifi_wep_key (const char *detail, validate_opt (detail, hash, "wep_tx_keyidx", TYPE_INT, GINT_TO_POINTER (0), -1); validate_opt (detail, hash, "wep_key0", TYPE_BYTES, expected, expected_size); + g_hash_table_unref (hash); g_object_unref (connection); } @@ -343,7 +345,7 @@ test_wifi_wpa_psk (const char *detail, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - NMSupplicantConfig *config; + gs_unref_object NMSupplicantConfig *config = NULL; GHashTable *hash; char *uuid; gboolean success; @@ -454,6 +456,7 @@ test_wifi_wpa_psk (const char *detail, validate_opt (detail, hash, "group", TYPE_KEYWORD, "TKIP CCMP", -1); validate_opt (detail, hash, "psk", key_type, expected, expected_size); + g_hash_table_unref (hash); g_object_unref (connection); } diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 65bc2199..a96d1ce9 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -86,6 +86,7 @@ EXTRA_DIST = test-secret-agent.py ########################################### +@VALGRIND_RULES@ TESTS = \ test-ip4-config \ test-ip6-config \ diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index a5d5b3a8..61e757e7 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -87,8 +97,6 @@ TESTS = test-ip4-config$(EXEEXT) test-ip6-config$(EXEEXT) \ test-general$(EXEEXT) test-general-with-expect$(EXEEXT) \ test-wired-defname$(EXEEXT) subdir = src/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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -105,6 +113,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -249,6 +258,8 @@ am__tty_colors = { \ fi; \ } DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -300,7 +311,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -335,6 +345,7 @@ 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@ @@ -626,7 +637,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/tests/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -701,14 +711,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1095,6 +1105,12 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +########################################### + +@VALGRIND_RULES@ @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ @for t in bond bridge ethernet gre infiniband macvlan tun veth vlan vxlan; do \ diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am index 66009c87..42c6b9a1 100644 --- a/src/tests/config/Makefile.am +++ b/src/tests/config/Makefile.am @@ -23,6 +23,7 @@ test_config_SOURCES = \ test_config_LDADD = \ $(top_builddir)/src/libNetworkManager.la +@VALGRIND_RULES@ TESTS = test-config EXTRA_DIST = \ diff --git a/src/tests/config/Makefile.in b/src/tests/config/Makefile.in index 81fb0885..73ff9d48 100644 --- a/src/tests/config/Makefile.in +++ b/src/tests/config/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,8 +91,6 @@ host_triplet = @host@ noinst_PROGRAMS = test-config$(EXEEXT) TESTS = test-config$(EXEEXT) subdir = src/tests/config -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/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -99,6 +107,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -194,6 +203,8 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -220,7 +231,6 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ 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@ @@ -255,6 +265,7 @@ 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@ @@ -500,7 +511,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/config/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/tests/config/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -546,14 +556,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -865,6 +875,10 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + + +@VALGRIND_RULES@ # 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/src/tests/config/nm-test-device.c b/src/tests/config/nm-test-device.c index 63067b25..512085e9 100644 --- a/src/tests/config/nm-test-device.c +++ b/src/tests/config/nm-test-device.c @@ -61,12 +61,6 @@ dispose (GObject *object) g_object_class->dispose (object); } -static void -finalize (GObject *object) -{ - g_object_class->finalize (object); -} - static guint32 get_generic_capabilities (NMDevice *device) { @@ -84,7 +78,6 @@ nm_test_device_class_init (NMTestDeviceClass *klass) object_class->constructor = constructor; object_class->constructed = constructed; object_class->dispose = dispose; - object_class->finalize = finalize; device_class->get_generic_capabilities = get_generic_capabilities; } diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index 808fc670..e027eab8 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -27,6 +27,10 @@ #include <nm-config.h> #include "nm-test-device.h" #include "nm-fake-platform.h" +#include "nm-logging.h" +#include "nm-dbus-manager.h" + +#include "nm-test-utils.h" static void setup_config (const char *config_file, const char *config_dir, ...) @@ -108,7 +112,7 @@ static void test_config_non_existent (void) { NMConfig *config; - GError *error = NULL; + gs_free_error GError *error = NULL; setup_config (SRCDIR "/no-such-file", "/no/such/dir", NULL); config = nm_config_new (&error); @@ -120,7 +124,7 @@ static void test_config_parse_error (void) { NMConfig *config; - GError *error = NULL; + gs_free_error GError *error = NULL; setup_config (SRCDIR "/bad.conf", "/no/such/dir", NULL); config = nm_config_new (&error); @@ -270,7 +274,7 @@ static void test_config_confdir_parse_error (void) { NMConfig *config; - GError *error = NULL; + gs_free_error GError *error = NULL; /* Using SRCDIR as the conf dir will pick up bad.conf */ setup_config (SRCDIR "/NetworkManager.conf", SRCDIR, NULL); @@ -279,14 +283,19 @@ test_config_confdir_parse_error (void) g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); } +NMTST_DEFINE (); + int main (int argc, char **argv) { -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_test_init (&argc, &argv, NULL); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); + + /* Initialize the DBus manager singleton explicitly, because it is accessed by + * the class initializer of NMDevice (used by the NMTestDevice stub). + * This way, we skip calling nm_dbus_manager_init_bus() which would + * either fail and/or cause unexpected actions in the test. + * */ + nm_dbus_manager_setup (g_object_new (NM_TYPE_DBUS_MANAGER, NULL)); nm_fake_platform_setup (); diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c index f5010dae..4a0627c9 100644 --- a/src/tests/test-general-with-expect.c +++ b/src/tests/test-general-with-expect.c @@ -333,16 +333,42 @@ test_nm_utils_kill_child (void) /*******************************************/ +static void +test_nm_ethernet_address_is_valid () +{ + g_assert (!nm_ethernet_address_is_valid (NULL, -1)); + g_assert (!nm_ethernet_address_is_valid (NULL, ETH_ALEN)); + + g_assert (!nm_ethernet_address_is_valid ("FF:FF:FF:FF:FF:FF", -1)); + g_assert (!nm_ethernet_address_is_valid ("00:00:00:00:00:00", -1)); + g_assert (!nm_ethernet_address_is_valid ("44:44:44:44:44:44", -1)); + g_assert (!nm_ethernet_address_is_valid ("00:30:b4:00:00:00", -1)); + + g_assert (!nm_ethernet_address_is_valid ("", -1)); + g_assert (!nm_ethernet_address_is_valid ("1", -1)); + g_assert (!nm_ethernet_address_is_valid ("2", -1)); + + g_assert (!nm_ethernet_address_is_valid (((guint8[8]) { 0x00,0x30,0xb4,0x00,0x00,0x00 }), ETH_ALEN)); + g_assert ( nm_ethernet_address_is_valid (((guint8[8]) { 0x00,0x30,0xb4,0x00,0x00,0x01 }), ETH_ALEN)); + + /* some Broad cast addresses (with MSB of first octet set). */ + g_assert (!nm_ethernet_address_is_valid ("57:44:44:44:44:44", -1)); + g_assert ( nm_ethernet_address_is_valid ("56:44:44:44:44:44", -1)); + g_assert (!nm_ethernet_address_is_valid (((guint8[8]) { 0x03,0x30,0xb4,0x00,0x00,0x00 }), ETH_ALEN)); + g_assert ( nm_ethernet_address_is_valid (((guint8[8]) { 0x02,0x30,0xb4,0x00,0x00,0x01 }), ETH_ALEN)); +} + +/*******************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv); - - nm_logging_setup ("DEBUG", "DEFAULT", NULL, NULL); + nmtst_init_assert_logging (&argc, &argv, "DEBUG", "DEFAULT"); g_test_add_func ("/general/nm_utils_kill_child", test_nm_utils_kill_child); + g_test_add_func ("/general/nm_ethernet_address_is_valid", test_nm_ethernet_address_is_valid); return g_test_run (); } diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c index a05588b8..b2933de0 100644 --- a/src/tests/test-wired-defname.c +++ b/src/tests/test-wired-defname.c @@ -26,6 +26,7 @@ #include <nm-simple-connection.h> #include <nm-setting-connection.h> #include "nm-device-ethernet-utils.h" +#include "gsystem-local-alloc.h" static NMConnection * _new_connection (const char *id) @@ -45,7 +46,7 @@ _new_connection (const char *id) static void test_defname_no_connections (void) { - char *name; + gs_free char *name = NULL; name = nm_device_ethernet_utils_get_default_wired_name (NULL); g_assert_cmpstr (name, ==, "Wired connection 1"); @@ -57,7 +58,7 @@ static void test_defname_no_conflict (void) { GSList *list = NULL; - char *name; + gs_free char *name = NULL; list = g_slist_append (list, _new_connection ("asdfasdfasdfadf")); list = g_slist_append (list, _new_connection ("work wifi")); @@ -75,7 +76,7 @@ static void test_defname_conflict (void) { GSList *list = NULL; - char *name; + gs_free char *name = NULL; list = g_slist_append (list, _new_connection ("asdfasdfasdfadf")); list = g_slist_append (list, _new_connection ("Wired connection 1")); @@ -93,7 +94,7 @@ static void test_defname_multiple_conflicts (void) { GSList *list = NULL; - char *name; + gs_free char *name = NULL; list = g_slist_append (list, _new_connection ("random gsm connection")); list = g_slist_append (list, _new_connection ("home wifi")); |